Compare commits
24 Commits
a3f2f04219
...
rough_for_
| Author | SHA1 | Date | |
|---|---|---|---|
| 9a5f1a5a54 | |||
| 0935aefeb2 | |||
| a0254d8e66 | |||
| 1285789b56 | |||
| 986188cf9d | |||
| df0df6ad4f | |||
| ee45d1d351 | |||
| 800c68655f | |||
| e7583fdb8d | |||
| b11fe50419 | |||
| af59f9d257 | |||
| 6c688f26cf | |||
| 860bddf0a3 | |||
| 2166a5827c | |||
| 02fe64012c | |||
| 6845626fe9 | |||
| ea024eafbc | |||
| c6161e7dd5 | |||
| 17eb1b34be | |||
| 334106006e | |||
| 1d791320eb | |||
| cbf871ca8c | |||
| 347fe0dbac | |||
| 7237188b7d |
18
debug_script/Replace_missing.py
Normal file
18
debug_script/Replace_missing.py
Normal file
@ -0,0 +1,18 @@
|
||||
from pathlib import Path
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
samp_np = 10395
|
||||
missing_second = 11495+11463-6300
|
||||
missing_length = 17.29-2.81
|
||||
fs = 500
|
||||
missging_bcg = Path(rf"E:\code\DataCombine2023\ZD5Y2\OrgBCG_Text\{samp_np}\OrgBCG_Raw_500.txt")
|
||||
|
||||
bcg_data = pd.read_csv(missging_bcg, header=None).to_numpy().reshape(-1)
|
||||
miss_start = int(missing_second * fs)
|
||||
bcg_data_filled = np.concatenate([bcg_data[:miss_start],
|
||||
np.full(int(missing_length * fs), np.mean(bcg_data)),
|
||||
bcg_data[miss_start:]])
|
||||
|
||||
output_path = Path(rf"E:\code\DataCombine2023\ZD5Y2\OrgBCG_Text\{samp_np}\OrgBCG_Raw_500_filled.txt")
|
||||
np.savetxt(output_path, bcg_data_filled, fmt="%d")
|
||||
71
debug_script/show_orgBcg_psg_resp.py
Normal file
71
debug_script/show_orgBcg_psg_resp.py
Normal file
@ -0,0 +1,71 @@
|
||||
from pathlib import Path
|
||||
from matplotlib import pyplot as plt
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from func.Filters.Preprocessing import Butterworth_for_ECG_PreProcess, Butterworth_for_BCG_PreProcess
|
||||
|
||||
# # 原始
|
||||
# psg_dir = Path(r"E:\code\DataCombine2023\ZD5Y2\PSG_Text\10787")
|
||||
# org_bcg_dir = Path(r"E:\code\DataCombine2023\ZD5Y2\OrgBCG_Text\10787")
|
||||
# tho_file_path = psg_dir / "Effort Tho_Raw_100.txt"
|
||||
# abd_file_path = psg_dir / "Effort Abd_Raw_100.txt"
|
||||
# tho_fs = 100
|
||||
# abd_fs = 100
|
||||
# orgbcg_file_path = org_bcg_dir / "OrgBCG_Raw_500.txt"
|
||||
# orgbcg_fs = 500
|
||||
|
||||
# 对齐后
|
||||
psg_dir = Path(r"E:\code\DataCombine2023\ZD5Y2\PSG_Aligned\10787")
|
||||
org_bcg_dir = Path(r"E:\code\DataCombine2023\ZD5Y2\OrgBCG_Aligned\10787")
|
||||
tho_file_path = psg_dir / "Effort Tho_Sync_100.txt"
|
||||
abd_file_path = psg_dir / "Effort Abd_Sync_100.txt"
|
||||
tho_fs = 100
|
||||
abd_fs = 100
|
||||
orgbcg_file_path = org_bcg_dir / "OrgBCG_Sync_1000.txt"
|
||||
orgbcg_fs = 1000
|
||||
|
||||
|
||||
tho_raw = pd.read_csv(tho_file_path, header=None).to_numpy().reshape(-1)
|
||||
abd_raw = pd.read_csv(abd_file_path, header=None).to_numpy().reshape(-1)
|
||||
orgbcg_raw = pd.read_csv(orgbcg_file_path, header=None).to_numpy().reshape(-1)
|
||||
|
||||
tho_filtered = Butterworth_for_ECG_PreProcess(tho_raw, tho_fs, type="bandpass", low_cut=0.01, high_cut=15.0, order=4)
|
||||
abd_filtered = Butterworth_for_ECG_PreProcess(abd_raw, abd_fs, type="bandpass", low_cut=0.01, high_cut=15.0, order=4)
|
||||
orgbcg_filtered = Butterworth_for_BCG_PreProcess(orgbcg_raw, orgbcg_fs, type="bandpass", low_cut=0.01, high_cut=0.7, order=4)
|
||||
|
||||
|
||||
# 降采样
|
||||
orgbcg_filtered = orgbcg_filtered[::orgbcg_fs//10] # 从500Hz降采样到10Hz
|
||||
tho_filtered = tho_filtered[::tho_fs//10] # 从100Hz降采样到10Hz
|
||||
abd_filtered = abd_filtered[::abd_fs//10] # 从100Hz降采样到10Hz
|
||||
|
||||
plt.figure(figsize=(12, 8))
|
||||
psg_x = np.linspace(0, len(tho_filtered) / 10, len(tho_filtered))
|
||||
orgbcg_x = np.linspace(0, len(orgbcg_filtered) / 10, len(orgbcg_filtered))
|
||||
|
||||
plt.subplot(3, 1, 1)
|
||||
plt.plot(psg_x, tho_filtered, label='Thoracic Effort', color='blue')
|
||||
plt.title('Thoracic Effort Signal (Filtered)')
|
||||
plt.xlabel('Time (s)')
|
||||
plt.ylabel('Amplitude')
|
||||
plt.grid()
|
||||
plt.legend()
|
||||
|
||||
plt.subplot(3, 1, 2)
|
||||
plt.plot(psg_x, abd_filtered, label='Abdominal Effort', color='green')
|
||||
plt.title('Abdominal Effort Signal (Filtered)')
|
||||
plt.xlabel('Time (s)')
|
||||
plt.ylabel('Amplitude')
|
||||
plt.grid()
|
||||
plt.legend()
|
||||
|
||||
plt.subplot(3, 1, 3)
|
||||
plt.plot(orgbcg_x, orgbcg_filtered, label='Original BCG', color='red')
|
||||
plt.title('Original BCG Signal (Filtered)')
|
||||
plt.xlabel('Time (s)')
|
||||
plt.ylabel('Amplitude')
|
||||
plt.grid()
|
||||
plt.legend()
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import traceback
|
||||
from gc import collect
|
||||
from pathlib import Path
|
||||
from traceback import format_exc
|
||||
@ -128,7 +129,9 @@ class SettingWindow(QMainWindow):
|
||||
|
||||
self.params.update({
|
||||
"Path": {
|
||||
|
||||
"psg_path": sync_psg_path,
|
||||
"bcg_path": sync_bcg_path,
|
||||
"label_path": label_path,
|
||||
"Input_OrgBCG": sync_bcg_path,
|
||||
"Input_Tho": sync_psg_path,
|
||||
"Input_Abd": sync_psg_path,
|
||||
@ -149,7 +152,7 @@ class SettingWindow(QMainWindow):
|
||||
|
||||
def __write_config__(self):
|
||||
# 从界面写入配置
|
||||
self.params["Path"]["Input_Stage"] = self.ui.plainTextEdit_file_path_input_signal_Stage().toPlainText()
|
||||
self.params["Path"]["Input_Stage"] = self.ui.plainTextEdit_file_path_input_signal_Stage.toPlainText()
|
||||
self.params["Path"]["Input_OrgBCG"] = self.ui.plainTextEdit_file_path_input_signal_OrgBCG.toPlainText()
|
||||
self.params["Path"]["Input_Tho"] = self.ui.plainTextEdit_file_path_input_signal_Tho.toPlainText()
|
||||
self.params["Path"]["Input_Abd"] = self.ui.plainTextEdit_file_path_input_signal_Abd.toPlainText()
|
||||
@ -195,7 +198,8 @@ class SettingWindow(QMainWindow):
|
||||
# self.ui.plainTextEdit_file_path_save_2.setPlainText(str(self.params["Path"]["Save_2"]))
|
||||
|
||||
def __auto_find_file__(self):
|
||||
check_signal_type_list = ["Input_OrgBCG", "Input_Tho", "Input_Abd", "Input_FlowT", "Input_FlowP", "Input_SpO2", "Input_Stage"]
|
||||
check_signal_type_list = ["Input_OrgBCG", "Input_Tho", "Input_Abd", "Input_FlowT", "Input_FlowP", "Input_SpO2",
|
||||
"Input_Stage"]
|
||||
|
||||
def find_file(file_path: Path, _type, endswith):
|
||||
if file_path.is_file():
|
||||
@ -209,8 +213,15 @@ class SettingWindow(QMainWindow):
|
||||
|
||||
self.params["Config"]["InputConfig"][f"{_type}Freq"] = result.data["freq"]
|
||||
else:
|
||||
self.params["Path"][f"Input_{_type}"] = file_path
|
||||
self.params["Config"]["InputConfig"][f"{_type}Freq"] = -1
|
||||
filename_start = filename_start.replace("Sync", "RoughCut")
|
||||
result = PublicFunc.examine_file(file_path, filename_start, endswith)
|
||||
if result.status:
|
||||
self.params["Path"][f"Input_{_type}"] = result.data["path"]
|
||||
|
||||
self.params["Config"]["InputConfig"][f"{_type}Freq"] = result.data["freq"]
|
||||
else:
|
||||
self.params["Path"][f"Input_{_type}"] = file_path
|
||||
self.params["Config"]["InputConfig"][f"{_type}Freq"] = -1
|
||||
|
||||
for signal_type in check_signal_type_list:
|
||||
signal_file_path = Path(self.params["Path"][signal_type])
|
||||
@ -258,7 +269,7 @@ class Data:
|
||||
self.channel = {
|
||||
"Stage": None,
|
||||
"orgdata": None,
|
||||
"0.7lowpass_resp": None,
|
||||
"0.5lowpass_resp": None,
|
||||
"Effort Tho": None,
|
||||
"Effort Abd": None,
|
||||
"Flow T": None,
|
||||
@ -298,14 +309,14 @@ class Data:
|
||||
"Input_SA_Label", "Input_Stage"]
|
||||
|
||||
for file_key in check_file_list:
|
||||
if (not self.config["Path"][file_key].is_file()) or (not self.config["Path"][file_key].exists()):
|
||||
if (not Path(self.config["Path"][file_key]).is_file()) or (not Path(self.config["Path"][file_key]).exists()):
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
|
||||
str(self.config["Path"][file_key]) +
|
||||
str(self.config["Path"][file_key]) + file_key +
|
||||
Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
|
||||
try:
|
||||
self.Stage = read_csv(self.config["Path"]["Input_Stage"], encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.OrgBCG = read_csv(self.config["Path"]["Input_OrgBCG"], encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.Tho = read_csv(self.config["Path"]["Input_Tho"], encoding=Params.UTF8_ENCODING,
|
||||
@ -319,7 +330,6 @@ class Data:
|
||||
self.SpO2 = read_csv(self.config["Path"]["Input_SpO2"], encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
|
||||
|
||||
if self.config["Path"]["Input_Artifact_A"].exists() and self.config["Path"]["Input_Artifact_A"].is_file():
|
||||
self.Artifact = read_csv(self.config["Path"]["Input_Artifact_A"],
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
@ -329,6 +339,7 @@ class Data:
|
||||
|
||||
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
|
||||
|
||||
@ -337,6 +348,7 @@ class Data:
|
||||
PublicFunc.examine_artifact(self.Artifact)
|
||||
self.Artifact = self.Artifact.reshape(-1, 4)
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
Constants.FAILURE_REASON[
|
||||
"Get_Artifact_Format_Exception"] + "\n" + format_exc())
|
||||
@ -345,7 +357,6 @@ class Data:
|
||||
"SignalSecond": int(len(self.OrgBCG) // self.config["Config"]["InputConfig"]["OrgBCGFreq"])
|
||||
})
|
||||
|
||||
|
||||
# 批量将睡眠分期按照映射转换为数字
|
||||
for stage_str, stage_val in self.stage_to_value.items():
|
||||
place(self.Stage, self.Stage == stage_str, stage_val)
|
||||
@ -360,7 +371,6 @@ class Data:
|
||||
self.SpO2 = self.SpO2[:self.config["SignalSecond"] * self.config["Config"]["InputConfig"]["SpO2Freq"]]
|
||||
self.Stage = self.Stage[:self.config["SignalSecond"]]
|
||||
|
||||
|
||||
plot_freq = self.config["Config"]["InputConfig"]["PlotFreq"]
|
||||
self.event_label_origin = zeros(self.config["SignalSecond"] * plot_freq)
|
||||
self.event_label_revised = zeros(self.config["SignalSecond"] * plot_freq)
|
||||
@ -440,6 +450,7 @@ class Data:
|
||||
self.event_index_revised[start:end] = one_data["Index"]
|
||||
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.FAILURE_REASON[
|
||||
"Label_Format_Exception"] + "\n" + format_exc())
|
||||
|
||||
@ -448,7 +459,10 @@ class Data:
|
||||
def preprocess(self):
|
||||
if self.OrgBCG is None:
|
||||
return Result().failure(info=Constants.PREPROCESS_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
|
||||
|
||||
if self.Tho is None:
|
||||
return Result().failure(info=Constants.PREPROCESS_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
|
||||
if self.Abd is None:
|
||||
return Result().failure(info=Constants.PREPROCESS_FAILURE + Constants.FAILURE_REASON["Data_Not_Exist"])
|
||||
try:
|
||||
plot_freq = self.config["Config"]["InputConfig"]["PlotFreq"]
|
||||
orgbcg_freq = self.config["Config"]["InputConfig"]["OrgBCGFreq"]
|
||||
@ -458,7 +472,8 @@ class Data:
|
||||
'lowpass', low_cut=20, order=3)
|
||||
self.lowPassResp = Butterworth_for_ECG_PreProcess(self.OrgBCG,
|
||||
orgbcg_freq,
|
||||
'lowpass', low_cut=0.7, order=3)
|
||||
'lowpass', low_cut=0.5, order=3)
|
||||
|
||||
self.artifact_label = zeros(len(self.event_label_origin))
|
||||
|
||||
for i, artifact_type, start, end in self.Artifact:
|
||||
@ -473,6 +488,7 @@ class Data:
|
||||
self.artifact_label[start:end] = artifact_type
|
||||
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.PREPROCESS_FAILURE +
|
||||
Constants.FAILURE_REASON["Preprocess_Exception"] + "\n" + format_exc())
|
||||
|
||||
@ -508,7 +524,7 @@ class Data:
|
||||
self.Stage_Resampled = _resample_signal(self.Stage, 1, plot_freq)
|
||||
|
||||
self.channel["orgdata"] = self.lowPass20Hz_Resampled
|
||||
self.channel["0.7lowpass_resp"] = self.lowPassResp_Resampled
|
||||
self.channel["0.5lowpass_resp"] = self.lowPassResp_Resampled
|
||||
self.channel["Effort Tho"] = self.Tho_Resampled
|
||||
self.channel["Effort Abd"] = self.Abd_Resampled
|
||||
self.channel["Flow T"] = self.FlowT_Resampled
|
||||
@ -526,6 +542,7 @@ class Data:
|
||||
del self.Stage
|
||||
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.RESAMPLE_FAILURE +
|
||||
Constants.FAILURE_REASON["Resample_Exception"] + "\n" + format_exc())
|
||||
|
||||
@ -538,10 +555,13 @@ class Data:
|
||||
try:
|
||||
self.df_revised.to_csv(self.config["Path"]["SA_Label_Revised"], mode='w', index=None, encoding="gbk")
|
||||
except PermissionError as e:
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Save_Permission_Denied"])
|
||||
except FileNotFoundError as e:
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Save_File_Not_Found"])
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.SAVE_FAILURE +
|
||||
Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc())
|
||||
|
||||
@ -589,9 +609,9 @@ class DataFrameModel(QAbstractTableModel):
|
||||
|
||||
# remark 返回蓝色 score 1 返回绿色, 2返回橙色 3返回灰色 -1返回红色
|
||||
# 获取此行的remark
|
||||
remark = not self._dataframe[self._dataframe["Index"] == event_index]["remark"].values[0]
|
||||
remark = self._dataframe[self._dataframe["Index"] == event_index]["remark"].values[0]
|
||||
score = self._dataframe[self._dataframe["Index"] == event_index]["score"].values[0]
|
||||
if str(remark).startswith("待讨论"):
|
||||
if "待讨论" in str(remark):
|
||||
return QColor(0, 0, 255)
|
||||
elif score == 1:
|
||||
return QColor(0, 255, 0)
|
||||
@ -606,6 +626,7 @@ class DataFrameModel(QAbstractTableModel):
|
||||
return QColor(0, 0, 0)
|
||||
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
return None
|
||||
|
||||
return None
|
||||
@ -799,7 +820,7 @@ class MainWindow_SA_label(QMainWindow):
|
||||
"Flow P": self.ax2,
|
||||
"Effort Tho": self.ax3,
|
||||
"Effort Abd": self.ax4,
|
||||
"0.7lowpass_resp": self.ax5,
|
||||
"0.5lowpass_resp": self.ax5,
|
||||
"orgdata": self.ax6,
|
||||
"Stage": self.ax7,
|
||||
}
|
||||
@ -811,7 +832,7 @@ class MainWindow_SA_label(QMainWindow):
|
||||
"Flow P": self.ui.checkBox_best_flow,
|
||||
"Effort Tho": self.ui.checkBox_best_effort,
|
||||
"Effort Abd": self.ui.checkBox_best_effort,
|
||||
"0.7lowpass_resp": self.ui.checkBox_best_resp,
|
||||
"0.5lowpass_resp": self.ui.checkBox_best_resp,
|
||||
"orgdata": self.ui.checkBox_best_raw,
|
||||
}
|
||||
|
||||
@ -863,8 +884,10 @@ class MainWindow_SA_label(QMainWindow):
|
||||
self.ui.pushButton_confirmLabel.clicked.connect(self.__slot_btn_confirmLabel__)
|
||||
self.ui.pushButton_reset_event.clicked.connect(self.__reset_event__)
|
||||
|
||||
self.ui.pushButton_next_half.setProperty("offset", int(self.ui.comboBox_window_signal_length.lineEdit().text()) // 2)
|
||||
self.ui.pushButton_previous_half.setProperty("offset", -int(self.ui.comboBox_window_signal_length.lineEdit().text()) // 2)
|
||||
self.ui.pushButton_next_half.setProperty("offset",
|
||||
int(self.ui.comboBox_window_signal_length.lineEdit().text()) // 2)
|
||||
self.ui.pushButton_previous_half.setProperty("offset",
|
||||
-int(self.ui.comboBox_window_signal_length.lineEdit().text()) // 2)
|
||||
|
||||
# 输入防抖
|
||||
self.debounce_timer1 = QTimer()
|
||||
@ -944,6 +967,7 @@ class MainWindow_SA_label(QMainWindow):
|
||||
self.set_tableview_column_width_by_ratio(self.ui.tableView_label_revised, [1, 3, 1, 2, 2])
|
||||
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.UPDATE_FAILURE +
|
||||
Constants.FAILURE_REASON["Update_tableWidget_Exception"] + "\n" + format_exc())
|
||||
|
||||
@ -965,8 +989,6 @@ class MainWindow_SA_label(QMainWindow):
|
||||
not self.channel_to_best_fit_checkbox[channel].isChecked()):
|
||||
continue
|
||||
|
||||
|
||||
|
||||
signal_max = self.data.channel[channel][start_point: end_point].max()
|
||||
signal_min = self.data.channel[channel][start_point: end_point].min()
|
||||
if channel == "SpO2":
|
||||
@ -1370,6 +1392,7 @@ class MainWindow_SA_label(QMainWindow):
|
||||
self.data.df_revised = self.data.df_revised[~mask].reset_index(drop=True)
|
||||
self.data.df_revised.to_csv(self.config["Path"]["SA_Label_Revised"], index=False, encoding="gbk")
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.SAVE_FAILURE +
|
||||
Constants.FAILURE_REASON["Save_revised_csv_Exception"] + "\n" + format_exc())
|
||||
return Result().success(info=Constants.SAVE_FINISHED)
|
||||
@ -2000,8 +2023,8 @@ class MainWindow_SA_label(QMainWindow):
|
||||
label_list=self.data.event_label_origin, event_code=[1, 2, 3, 4])
|
||||
self.plt_channel(channel="Effort Abd", start=0, end=self.config["SignalSecond"],
|
||||
label_list=self.data.event_label_origin, event_code=[1, 2, 3, 4])
|
||||
self.plt_channel(channel="0.7lowpass_resp", start=0, end=self.config["SignalSecond"])
|
||||
self.plt_interactive_event(channel="0.7lowpass_resp", label_df=self.data.df_revised)
|
||||
self.plt_channel(channel="0.5lowpass_resp", start=0, end=self.config["SignalSecond"])
|
||||
self.plt_interactive_event(channel="0.5lowpass_resp", label_df=self.data.df_revised)
|
||||
self.plt_channel(channel="orgdata", start=0, end=self.config["SignalSecond"],
|
||||
label_list=self.data.artifact_label, event_code=[6, 7, 8, 9, 10])
|
||||
self.plt_channel(channel="Stage", start=0, end=self.config["SignalSecond"])
|
||||
@ -2009,6 +2032,7 @@ class MainWindow_SA_label(QMainWindow):
|
||||
self.ax0.set_xlim(self.check_start_end(self.config["WindowStartSecond"], 0))
|
||||
self.canvas.draw()
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.DRAW_FAILURE + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.DRAW_FINISHED)
|
||||
|
||||
@ -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)
|
||||
@ -1472,13 +1499,21 @@ class Data:
|
||||
theilsen = TheilSenRegressor()
|
||||
theilsen.fit(X, y)
|
||||
slope = theilsen.coef_[0]
|
||||
frequency = 1 - slope / epoch_second / temp_freq if slope != 0 else float('inf')
|
||||
# frequency = 1 - slope / epoch_second / temp_freq if slope != 0 else float('inf')
|
||||
if slope != 0:
|
||||
drift_rate = slope / epoch_second
|
||||
# frequency = temp_freq * (1 - drift_rate)
|
||||
# frequency_ratio = 1 - drift_rate
|
||||
frequency_ratio = 1 / (1 + drift_rate)
|
||||
else:
|
||||
# frequency = float(temp_freq)
|
||||
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_},
|
||||
)
|
||||
|
||||
@ -1,358 +0,0 @@
|
||||
from ast import literal_eval
|
||||
from gc import collect
|
||||
from math import floor
|
||||
from pathlib import Path
|
||||
from traceback import format_exc
|
||||
|
||||
from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication
|
||||
from numpy import array
|
||||
from overrides import overrides
|
||||
from pandas import read_csv, DataFrame
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.ConfigParams import Filename, Params
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants
|
||||
from func.utils.Result import Result
|
||||
|
||||
from ui.MainWindow.MainWindow_cut_PSG import Ui_MainWindow_cut_PSG
|
||||
|
||||
|
||||
Config = {
|
||||
|
||||
}
|
||||
|
||||
ButtonState = {
|
||||
"Default": {
|
||||
"pushButton_execute": True
|
||||
},
|
||||
"Current": {
|
||||
"pushButton_execute": True
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MainWindow_cut_PSG(QMainWindow):
|
||||
|
||||
def __init__(self):
|
||||
super(MainWindow_cut_PSG, self).__init__()
|
||||
self.ui = Ui_MainWindow_cut_PSG()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
self.root_path = None
|
||||
self.sampID = None
|
||||
|
||||
self.__read_config__()
|
||||
|
||||
self.data = None
|
||||
|
||||
self.ui.textBrowser_info.setStyleSheet("QTextBrowser { background-color: rgb(255, 255, 200); }")
|
||||
PublicFunc.__styleAllButton__(self, ButtonState)
|
||||
|
||||
# 初始化进度条
|
||||
self.ui.progressbar.setStyleSheet(Constants.PROGRESSBAR_STYLE)
|
||||
self.progressbar = self.ui.progressbar
|
||||
|
||||
self.msgBox = QMessageBox()
|
||||
self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE)
|
||||
|
||||
@overrides
|
||||
def show(self, root_path, sampID):
|
||||
super().show()
|
||||
self.root_path = root_path
|
||||
self.sampID = sampID
|
||||
|
||||
PublicFunc.__resetAllButton__(self, ButtonState)
|
||||
|
||||
Config.update({
|
||||
"Path": {
|
||||
"InputFolder": str(Path(self.root_path) / Filename.PATH_PSG_TEXT / Path(str(self.sampID))),
|
||||
"SaveFolder": str(Path(self.root_path) / Filename.PATH_PSG_ALIGNED / Path(str(self.sampID))),
|
||||
"InputAlignInfo": str(Path(self.root_path) / Filename.PATH_LABEL / Path(str(self.sampID)))
|
||||
}
|
||||
})
|
||||
|
||||
self.ui.plainTextEdit_channel.setPlainText(', '.join(Config["ChannelInput"].keys()))
|
||||
self.ui.plainTextEdit_label.setPlainText(', '.join(Config["LabelInput"].keys()))
|
||||
|
||||
self.ui.pushButton_execute.clicked.connect(self.__slot_btn_execute__)
|
||||
|
||||
@overrides
|
||||
def closeEvent(self, event):
|
||||
reply = QMessageBox.question(self, '确认', '确认退出吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
||||
if reply == QMessageBox.Yes:
|
||||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||||
|
||||
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
|
||||
QApplication.processEvents()
|
||||
|
||||
# 释放资源
|
||||
del self.data
|
||||
self.deleteLater()
|
||||
collect()
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def __reset__(self):
|
||||
ButtonState["Current"].update(ButtonState["Default"].copy())
|
||||
|
||||
def __read_config__(self):
|
||||
if not Path(Params.CUT_PSG_CONFIG_FILE_PATH).exists():
|
||||
with open(Params.CUT_PSG_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.CUT_PSG_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(Params.CUT_PSG_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
|
||||
# 数据回显
|
||||
self.ui.spinBox_ECGFreq.setValue(Config["ECGFreq"])
|
||||
|
||||
def __slot_btn_execute__(self):
|
||||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||||
|
||||
self.data = Data(self.root_path, self.sampID)
|
||||
Config["ECGFreq"] = self.ui.spinBox_ECGFreq.value()
|
||||
|
||||
# 检查文件是否存在并获取其数据采样率
|
||||
PublicFunc.progressbar_update(self, 1, 5, Constants.CUT_PSG_GETTING_FILE_AND_FREQ, 0)
|
||||
result = self.data.get_file_and_freq()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(1/5)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(1/5)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
# 导入数据
|
||||
PublicFunc.progressbar_update(self, 2, 5, Constants.INPUTTING_DATA, 10)
|
||||
result = self.data.open_file()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(2/5)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(2/5)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
# 切割数据
|
||||
PublicFunc.progressbar_update(self, 3, 5, Constants.CUT_PSG_CUTTING_DATA, 40)
|
||||
result = self.data.cut_data()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(3/5)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(3/5)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
# 标签映射
|
||||
PublicFunc.progressbar_update(self, 4, 5, Constants.CUT_PSG_ALIGNING_LABEL, 60)
|
||||
result = self.data.align_label()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(4/5)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(4/5)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
# 保存数据
|
||||
PublicFunc.progressbar_update(self, 5, 5, Constants.SAVING_DATA, 70)
|
||||
result = self.data.save()
|
||||
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(5/5)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(5/5)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
for key, raw in self.data.raw.items():
|
||||
info = "保存{}的长度为{},采样率为{}Hz".format(key, str(len(raw)), str(self.data.freq[key]))
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
QApplication.processEvents()
|
||||
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
|
||||
class Data:
|
||||
|
||||
def __init__(self, root_path, sampID):
|
||||
self.alignInfo = None
|
||||
|
||||
self.raw = {key: array([]) for key in Config["ChannelInput"]}
|
||||
self.freq = {key: 0 for key in Config["ChannelInput"]}
|
||||
|
||||
self.SALabel = None
|
||||
self.startTime = None
|
||||
|
||||
self.root_path = root_path
|
||||
self.sampID = sampID
|
||||
|
||||
def get_file_and_freq(self):
|
||||
try:
|
||||
for file_path in Path(Config["Path"]["InputFolder"]).glob('*'):
|
||||
if file_path.is_file():
|
||||
file_stem = Path(file_path).stem
|
||||
for key, prefix in Config["ChannelInput"].items():
|
||||
if file_stem.startswith(prefix):
|
||||
freq_str = file_stem.rsplit('_', 1)[1]
|
||||
try:
|
||||
freq = int(freq_str)
|
||||
self.freq[key] = freq
|
||||
except ValueError:
|
||||
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["Filename_Format_not_Correct"] + f"\n{Config['ChannelInput']}")
|
||||
for value in self.freq.values():
|
||||
if value == 0:
|
||||
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["Filename_Format_not_Correct"] + f"\n{Config['ChannelInput']}")
|
||||
if not any((Config["LabelInput"]["SA Label"] + Config["EndWith"]["SA Label"]) in str(file) for file in Path(Config["Path"]["InputFolder"]).glob('*')):
|
||||
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["File_Not_Exist"])
|
||||
if not any((Config["StartTime"] + Config["EndWith"]["StartTime"]) in str(file) for file in Path(Config["Path"]["InputFolder"]).glob('*')):
|
||||
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["File_Not_Exist"])
|
||||
if not Path(Config["Path"]["InputAlignInfo"]).exists():
|
||||
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["File_Not_Exist"])
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["Get_File_and_Freq_Excepetion"] + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.CUT_PSG_GET_FILE_AND_FREQ_FINISHED)
|
||||
|
||||
def open_file(self):
|
||||
path = str(Path(self.root_path) / Filename.PATH_PSG_TEXT / Path(str(self.sampID)))
|
||||
for value in Config["ChannelInput"].values():
|
||||
result = PublicFunc.examine_file(path, value, Params.ENDSWITH_TXT)
|
||||
if not result.status:
|
||||
return result
|
||||
|
||||
if Path(Config["Path"]["InputAlignInfo"]).is_file():
|
||||
Config["Path"]["InputAlignInfo"] = str(Path(Config["Path"]["InputAlignInfo"]).parent)
|
||||
|
||||
Config["Path"]["InputAlignInfo"] = str(
|
||||
Path(Config["Path"]["InputAlignInfo"]) / Path(
|
||||
Filename.PRECISELY_ALIGN_INFO + Params.ENDSWITH_TXT))
|
||||
|
||||
try:
|
||||
for key in Config["ChannelInput"].keys():
|
||||
self.raw[key] = read_csv(Path(Config["Path"]["InputFolder"]) / Path((Config["ChannelInput"][key] + str(self.freq[key]) + Config["EndWith"][key])),
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
self.SALabel = read_csv(Path(Config["Path"]["InputFolder"]) / Path((Config["LabelInput"]["SA Label"] + Config["EndWith"]["SA Label"])),
|
||||
encoding=Params.GBK_ENCODING)
|
||||
self.startTime = read_csv(Path(Config["Path"]["InputFolder"]) / 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])
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.INPUT_FINISHED)
|
||||
|
||||
def cut_data(self):
|
||||
try:
|
||||
for key, raw in self.raw.items():
|
||||
# 转换切割点
|
||||
ECG_freq = Config["ECGFreq"]
|
||||
raw_freq = self.freq[key]
|
||||
duration_second = ((self.alignInfo["cut_index"]["back_ECG"] - self.alignInfo["cut_index"]["front_ECG"]) // ECG_freq) + 1
|
||||
start_index_cut = floor(self.alignInfo["cut_index"]["front_ECG"] * (raw_freq / ECG_freq))
|
||||
end_index_cut = start_index_cut + (duration_second * raw_freq)
|
||||
|
||||
try:
|
||||
# 切割信号
|
||||
self.raw[key] = self.raw[key][start_index_cut:end_index_cut]
|
||||
except Exception:
|
||||
return Result().failure(info=Constants.CUT_PSG_CUT_DATA_FAILURE +
|
||||
Constants.FAILURE_REASON["Cut_Data_Length_not_Correct"])
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.CUT_PSG_CUT_DATA_FAILURE +
|
||||
Constants.FAILURE_REASON["Cut_Data_Exception"] + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.CUT_PSG_CUT_DATA_FINISHED)
|
||||
|
||||
def align_label(self):
|
||||
try:
|
||||
# 读取SA标签
|
||||
self.SALabel = self.SALabel.loc[:, ~self.SALabel.columns.str.contains("^Unnamed")]
|
||||
self.SALabel = self.SALabel[self.SALabel["Event type"].isin(Params.CUT_PSG_SALABEL_EVENT)]
|
||||
self.SALabel["Duration"] = self.SALabel["Duration"].astype(str)
|
||||
self.SALabel["Duration"] = self.SALabel["Duration"].str.replace(r' \(.*?\)', '', regex=True)
|
||||
except Exception:
|
||||
return Result().failure(info=Constants.CUT_PSG_ALIGN_LABEL_FAILURE +
|
||||
Constants.FAILURE_REASON["Align_Label_SALabel_Format_not_Correct"])
|
||||
|
||||
try:
|
||||
# 获取记录开始时间
|
||||
start_time = str(self.startTime[0]).split(" ")[1]
|
||||
start_time = Data.get_time_to_seconds(start_time)
|
||||
|
||||
# 计算起始时间秒数和终止时间秒数
|
||||
self.SALabel["Start"] = (self.SALabel["Time"].apply(self.get_time_to_seconds) - start_time).apply(
|
||||
lambda x: x + 24 * 3600 if x < 0 else x).astype(int)
|
||||
self.SALabel["End"] = self.SALabel["Start"] + self.SALabel["Duration"].astype(float).round(0).astype(int)
|
||||
|
||||
# 标签映射
|
||||
ECG_length = self.alignInfo["cut_index"]["back_ECG"] - self.alignInfo["cut_index"]["front_ECG"]
|
||||
self.SALabel["Start"] = self.SALabel["Start"] - round((self.alignInfo["cut_index"]["front_ECG"] / 1000))
|
||||
self.SALabel["End"] = self.SALabel["End"] - round((self.alignInfo["cut_index"]["front_ECG"] / 1000))
|
||||
self.SALabel = self.SALabel[self.SALabel["End"] >= 0]
|
||||
self.SALabel.loc[self.SALabel["Start"] < 0, "Start"] = 0
|
||||
self.SALabel = self.SALabel[self.SALabel["Start"] < ECG_length]
|
||||
self.SALabel.loc[self.SALabel["End"] >= ECG_length, "End"] = ECG_length - 1
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.CUT_PSG_ALIGN_LABEL_FAILURE +
|
||||
Constants.FAILURE_REASON["Align_Label_Exception"] + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.CUT_PSG_ALIGN_LABEL_FINISHED)
|
||||
|
||||
def save(self):
|
||||
for raw in self.raw.values():
|
||||
if len(raw) == 0:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE +
|
||||
Constants.FAILURE_REASON["Data_not_Exist"])
|
||||
|
||||
try:
|
||||
for key, raw in self.raw.items():
|
||||
DataFrame(raw.reshape(-1)).to_csv(Path(Config["Path"]["SaveFolder"]) / Path((Config["ChannelSave"][key] + str(self.freq[key]) + Config["EndWith"][key])),
|
||||
index=False, header=False)
|
||||
# 重排index,从1开始,并给index命名
|
||||
self.SALabel.sort_values(by=["Start"], inplace=True)
|
||||
self.SALabel.reset_index(drop=True, inplace=True)
|
||||
self.SALabel.index = self.SALabel.index + 1
|
||||
self.SALabel.index.name = "Index"
|
||||
self.SALabel.to_csv(Path(Config["Path"]["SaveFolder"]) / Path((Config["LabelSave"]["SA Label"] + Config["EndWith"]["SA Label"])),
|
||||
encoding="gbk")
|
||||
except PermissionError as e:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Save_Permission_Denied"])
|
||||
except FileNotFoundError as e:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Save_File_Not_Found"])
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE +
|
||||
Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.SAVE_FINISHED)
|
||||
|
||||
@staticmethod
|
||||
def get_time_to_seconds(time_str):
|
||||
h, m, s = map(int, time_str.split(":"))
|
||||
return h * 3600 + m * 60 + s
|
||||
656
func/Module_cut_pair_file.py
Normal file
656
func/Module_cut_pair_file.py
Normal file
@ -0,0 +1,656 @@
|
||||
import re
|
||||
import traceback
|
||||
from ast import literal_eval
|
||||
from gc import collect
|
||||
from math import floor, ceil
|
||||
from pathlib import Path
|
||||
from traceback import format_exc
|
||||
|
||||
import soxr
|
||||
from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication
|
||||
from numpy import array
|
||||
from overrides import overrides
|
||||
from pandas import read_csv, DataFrame
|
||||
from yaml import dump, load, FullLoader
|
||||
import numpy as np
|
||||
from func.utils.ConfigParams import Filename, Params
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants
|
||||
from func.utils.Result import Result
|
||||
from numpy import float32
|
||||
from ui.MainWindow.MainWindow_cut_PAIR_FILE import Ui_MainWindow_cut_PAIR_FILE
|
||||
|
||||
|
||||
Config = {
|
||||
|
||||
}
|
||||
|
||||
ButtonState = {
|
||||
"Default": {
|
||||
"checkBox_roughCut": True,
|
||||
"checkBox_roughResample": False,
|
||||
"pushButton_deleteRoughCut": False,
|
||||
"pushButton_execute": True,
|
||||
"spinBox_OrgBCGShift": False
|
||||
},
|
||||
"Current": {
|
||||
"checkBox_roughCut": True,
|
||||
"checkBox_roughResample": False,
|
||||
"pushButton_deleteRoughCut": False,
|
||||
"pushButton_execute": True,
|
||||
"spinBox_OrgBCGShift": False
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MainWindow_cut_PAIR_FILE(QMainWindow):
|
||||
|
||||
def __init__(self):
|
||||
super(MainWindow_cut_PAIR_FILE, self).__init__()
|
||||
self.ui = Ui_MainWindow_cut_PAIR_FILE()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
self.root_path = None
|
||||
self.sampID = None
|
||||
|
||||
self.__read_config__()
|
||||
|
||||
self.data = None
|
||||
|
||||
self.ui.textBrowser_info.setStyleSheet("QTextBrowser { background-color: rgb(255, 255, 200); }")
|
||||
PublicFunc.__styleAllButton__(self, ButtonState)
|
||||
|
||||
# 初始化进度条
|
||||
self.ui.progressbar.setStyleSheet(Constants.PROGRESSBAR_STYLE)
|
||||
self.progressbar = self.ui.progressbar
|
||||
|
||||
self.msgBox = QMessageBox()
|
||||
self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE)
|
||||
|
||||
@overrides
|
||||
def show(self, root_path, sampID):
|
||||
super().show()
|
||||
self.root_path = root_path
|
||||
self.sampID = sampID
|
||||
|
||||
PublicFunc.__resetAllButton__(self, ButtonState)
|
||||
|
||||
Config.update({
|
||||
"Path": {
|
||||
"InputPSGFolder": str(Path(self.root_path) / Filename.PATH_PSG_TEXT / Path(str(self.sampID))),
|
||||
"SavePSGFolder": str(Path(self.root_path) / Filename.PATH_PSG_ALIGNED / Path(str(self.sampID))),
|
||||
"InputAlignInfo": str(Path(self.root_path) / Filename.PATH_LABEL / Path(str(self.sampID))),
|
||||
"InputOrgBCGFolder": str(Path(self.root_path) / Filename.PATH_ORGBCG_TEXT / Path(str(self.sampID))),
|
||||
"SaveOrgBCGFolder": str(Path(self.root_path) / Filename.PATH_ORGBCG_ALIGNED / Path(str(self.sampID)))
|
||||
}
|
||||
})
|
||||
|
||||
self.ui.plainTextEdit_channel.setPlainText(', '.join(Config["ChannelInput"].keys()))
|
||||
self.ui.plainTextEdit_label.setPlainText(', '.join(Config["LabelInput"].keys()))
|
||||
|
||||
self.ui.pushButton_execute.clicked.connect(self.__slot_btn_execute__)
|
||||
self.ui.checkBox_roughCut.stateChanged.connect(self.__change_approximate_align_mode__)
|
||||
self.ui.pushButton_deleteRoughCut.clicked.connect(self.__delete_rough_cut_file__)
|
||||
|
||||
self.ui.spinBox_OrgBCGShift.setEnabled(False)
|
||||
|
||||
|
||||
@overrides
|
||||
def closeEvent(self, event):
|
||||
reply = QMessageBox.question(self, '确认', '确认退出吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
||||
if reply == QMessageBox.Yes:
|
||||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||||
|
||||
PublicFunc.statusbar_show_msg(self, PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
|
||||
QApplication.processEvents()
|
||||
|
||||
# 释放资源
|
||||
del self.data
|
||||
self.deleteLater()
|
||||
collect()
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def __reset__(self):
|
||||
ButtonState["Current"].update(ButtonState["Default"].copy())
|
||||
|
||||
def __read_config__(self):
|
||||
if not Path(Params.CUT_PAIR_FILE_CONFIG_FILE_PATH).exists():
|
||||
with open(Params.CUT_PAIR_FILE_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(Params.CUT_PAIR_FILE_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(Params.CUT_PAIR_FILE_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
|
||||
# 数据回显
|
||||
self.ui.spinBox_ECGFreq.setValue(Config["ECGFreq"])
|
||||
|
||||
|
||||
def __change_approximate_align_mode__(self):
|
||||
# ChannelInput 添加OrgBCGCHannelInput
|
||||
if self.ui.checkBox_roughCut.isChecked():
|
||||
Config["ChannelInput"].update(Config["OrgBCGChannelInput"])
|
||||
Config["ChannelInput"].update(Config["ECGChannelInput"])
|
||||
|
||||
# 修改ChannelSave中的Sync为RoughCut
|
||||
for key in Config["ChannelSave"].keys():
|
||||
if "Sync" in Config["ChannelSave"][key]:
|
||||
Config["ChannelSave"][key] = Config["ChannelSave"][key].replace("Sync", "RoughCut")
|
||||
|
||||
ButtonState["Default"]["pushButton_deleteRoughCut"] = True
|
||||
ButtonState["Default"]["checkBox_roughResample"] = True
|
||||
self.ui.plainTextEdit_channel.setPlainText(', '.join(Config["ChannelInput"].keys()))
|
||||
self.ui.spinBox_OrgBCGShift.setEnabled(True)
|
||||
ButtonState["Current"]["pushButton_deleteRoughCut"] = True
|
||||
ButtonState["Current"]["checkBox_roughResample"] = True
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
else:
|
||||
# ChannelInput 移除OrgBCGCHannelInput
|
||||
for key in Config["OrgBCGChannelInput"].keys():
|
||||
if key in Config["ChannelInput"]:
|
||||
Config["ChannelInput"].pop(key)
|
||||
for key in Config["ECGChannelInput"].keys():
|
||||
if key in Config["ChannelInput"]:
|
||||
Config["ChannelInput"].pop(key)
|
||||
# print(Config["ChannelInput"])
|
||||
# 修改ChannelSave中的RoughCut为Sync
|
||||
for key in Config["ChannelSave"].keys():
|
||||
if "RoughCut" in Config["ChannelSave"][key]:
|
||||
Config["ChannelSave"][key] = Config["ChannelSave"][key].replace("RoughCut", "Sync")
|
||||
ButtonState["Default"]["pushButton_deleteRoughCut"] = False
|
||||
ButtonState["Default"]["checkBox_roughResample"] = False
|
||||
self.ui.plainTextEdit_channel.setPlainText(', '.join(Config["ChannelInput"].keys()))
|
||||
self.ui.spinBox_OrgBCGShift.setEnabled(False)
|
||||
ButtonState["Current"]["pushButton_deleteRoughCut"] = False
|
||||
ButtonState["Current"]["checkBox_roughResample"] = False
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
|
||||
def __slot_btn_execute__(self):
|
||||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||||
|
||||
self.data = Data(self.root_path, self.sampID)
|
||||
Config["ECGFreq"] = self.ui.spinBox_ECGFreq.value()
|
||||
|
||||
# 检查文件是否存在并获取其数据采样率
|
||||
PublicFunc.progressbar_update(self, 1, 5, Constants.CUT_PAIR_FILE_GETTING_FILE_AND_FREQ, 0)
|
||||
result = self.data.get_file_and_freq()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(1/5)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
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)
|
||||
|
||||
# 导入数据
|
||||
PublicFunc.progressbar_update(self, 2, 5, Constants.INPUTTING_DATA, 10)
|
||||
result = self.data.open_file()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(2/5)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(2/5)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
if self.ui.checkBox_roughCut.isChecked():
|
||||
# 获取或计算粗对齐信息
|
||||
PublicFunc.progressbar_update(self, 3, 5, Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO, 20)
|
||||
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)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(3/5)" + Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_FINISHED, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
if self.ui.checkBox_roughResample.isChecked():
|
||||
result_resample = self.data.resample_BCG()
|
||||
if not result_resample.status:
|
||||
PublicFunc.text_output(self.ui, "(3/5)" + result_resample.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result_resample.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(3/5)" + result_resample.info, 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)
|
||||
|
||||
# 切割数据
|
||||
PublicFunc.progressbar_update(self, 3, 5, Constants.CUT_PAIR_FILE_CUTTING_DATA, 40)
|
||||
PublicFunc.text_output(self.ui, "(3/5)" + str(self.data.alignInfo["cut_index"]), Constants.TIPS_TYPE_INFO)
|
||||
result = self.data.cut_data()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(3/5)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(3/5)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
# 标签映射
|
||||
PublicFunc.progressbar_update(self, 4, 5, Constants.CUT_PAIR_FILE_ALIGNING_LABEL, 60)
|
||||
result = self.data.align_label()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(4/5)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(4/5)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
# 保存数据
|
||||
PublicFunc.progressbar_update(self, 5, 5, Constants.SAVING_DATA, 70)
|
||||
|
||||
result = self.data.save()
|
||||
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(5/5)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(5/5)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
for key, raw in self.data.raw.items():
|
||||
info = "保存{}的长度为{},采样率为{}Hz".format(key, str(len(raw)), str(self.data.freq[key]))
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
QApplication.processEvents()
|
||||
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
def __delete_rough_cut_file__(self):
|
||||
PublicFunc.__disableAllButton__(self, ButtonState)
|
||||
|
||||
self.data = Data(self.root_path, self.sampID)
|
||||
|
||||
# 删除粗切割文件
|
||||
PublicFunc.progressbar_update(self, 1, 1, Constants.CUT_PAIR_FILE_DELETING_ROUGH_CUT_FILE, 50)
|
||||
result = self.data.delete_rough_cut_file()
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(1/1)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, "(1/1)" + result.info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_INFO)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
|
||||
class Data:
|
||||
|
||||
def __init__(self, root_path, sampID):
|
||||
self.actualBCGFreq = None
|
||||
self.TimeBiasSecond = None
|
||||
self.alignInfo = None
|
||||
|
||||
self.raw = {key: array([]) for key in Config["ChannelInput"]}
|
||||
self.freq = {key: 0 for key in Config["ChannelInput"]}
|
||||
|
||||
self.SALabel = None
|
||||
self.startTime = None
|
||||
|
||||
self.root_path = root_path
|
||||
self.sampID = sampID
|
||||
|
||||
def get_file_and_freq(self):
|
||||
try:
|
||||
for file_path in Path(Config["Path"]["InputPSGFolder"]).glob('*'):
|
||||
if file_path.is_file():
|
||||
file_stem = Path(file_path).stem
|
||||
for key, prefix in Config["ChannelInput"].items():
|
||||
if not prefix.startswith("PSG:"):
|
||||
continue
|
||||
prefix = prefix[len("PSG:"):]
|
||||
if file_stem.startswith(prefix):
|
||||
freq_str = file_stem.rsplit('_', 1)[1]
|
||||
try:
|
||||
freq = int(freq_str)
|
||||
self.freq[key] = freq
|
||||
except ValueError:
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["Filename_Format_not_Correct"] + f"\n{Config['ChannelInput']}")
|
||||
|
||||
for file_path in Path(Config["Path"]["InputOrgBCGFolder"]).glob('*'):
|
||||
if file_path.is_file():
|
||||
file_stem = Path(file_path).stem
|
||||
for key, prefix in Config["ChannelInput"].items():
|
||||
if not prefix.startswith("OrgBCG:"):
|
||||
continue
|
||||
prefix = prefix[len("OrgBCG:"):]
|
||||
if file_stem.startswith(prefix):
|
||||
freq_str = file_stem.rsplit('_', 1)[1]
|
||||
try:
|
||||
freq = int(freq_str)
|
||||
self.freq[key] = freq
|
||||
except ValueError:
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["Filename_Format_not_Correct"] + f"\n{Config['ChannelInput']}")
|
||||
|
||||
for value in self.freq.values():
|
||||
if value == 0:
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["Filename_Format_not_Correct"] + f"\n{Config['ChannelInput']}")
|
||||
if not any((Config["LabelInput"]["SA Label"] + Config["EndWith"]["SA Label"]) in str(file) for file in Path(Config["Path"]["InputPSGFolder"]).glob('*')):
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["File_Not_Exist"])
|
||||
if not any((Config["StartTime"] + Config["EndWith"]["StartTime"]) in str(file) for file in Path(Config["Path"]["InputPSGFolder"]).glob('*')):
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["File_Not_Exist"])
|
||||
if not Path(Config["Path"]["InputAlignInfo"]).exists():
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["File_Not_Exist"])
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_GET_FILE_AND_FREQ_FAILURE +
|
||||
Constants.FAILURE_REASON["Get_File_and_Freq_Excepetion"] + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.CUT_PAIR_FILE_GET_FILE_AND_FREQ_FINISHED)
|
||||
|
||||
def open_file(self):
|
||||
psg_path = str(Path(self.root_path) / Filename.PATH_PSG_TEXT / Path(str(self.sampID)))
|
||||
bcg_path = str(Path(self.root_path) / Filename.PATH_ORGBCG_TEXT / Path(str(self.sampID)))
|
||||
for value in Config["ChannelInput"].values():
|
||||
if value.startswith("PSG:"):
|
||||
value = value[len("PSG:"):]
|
||||
result = PublicFunc.examine_file(psg_path, value, Params.ENDSWITH_TXT)
|
||||
if not result.status:
|
||||
return result
|
||||
elif value.startswith("OrgBCG:"):
|
||||
value = value[len("OrgBCG:"):]
|
||||
result = PublicFunc.examine_file(bcg_path, value, Params.ENDSWITH_TXT)
|
||||
if not result.status:
|
||||
return result
|
||||
|
||||
if Path(Config["Path"]["InputAlignInfo"]).is_file():
|
||||
Config["Path"]["InputAlignInfo"] = str(Path(Config["Path"]["InputAlignInfo"]).parent)
|
||||
|
||||
Config["Path"]["Input_Approximately_Align"] = str(
|
||||
Path(Config["Path"]["InputAlignInfo"]) / Path(
|
||||
Filename.APPROXIMATELY_ALIGN_INFO + Params.ENDSWITH_CSV))
|
||||
|
||||
Config["Path"]["InputAlignInfo"] = str(
|
||||
Path(Config["Path"]["InputAlignInfo"]) / Path(
|
||||
Filename.PRECISELY_ALIGN_INFO + Params.ENDSWITH_TXT))
|
||||
|
||||
try:
|
||||
for key in Config["ChannelInput"].keys():
|
||||
if not Config["ChannelInput"][key].startswith("OrgBCG"):
|
||||
self.raw[key] = read_csv(Path(Config["Path"]["InputPSGFolder"]) / Path((Config["ChannelInput"][key][len("PSG:"):] + str(self.freq[key]) + Config["EndWith"][key])),
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
|
||||
elif Config["ChannelInput"][key].startswith("OrgBCG"):
|
||||
self.raw[key] = read_csv(Path(Config["Path"]["InputOrgBCGFolder"]) / Path((Config["ChannelInput"][key][len("OrgBCG:"):] + str(self.freq[key]) + Config["EndWith"][key])),
|
||||
encoding=Params.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
|
||||
self.SALabel = read_csv(Path(Config["Path"]["InputPSGFolder"]) / Path((Config["LabelInput"]["SA Label"] + Config["EndWith"]["SA Label"])),
|
||||
encoding=Params.GBK_ENCODING)
|
||||
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)
|
||||
cleaned_str = re.sub(r'np\.\w+\(\s*([^)]+?)\s*\)', r'\1', self.alignInfo[0])
|
||||
self.alignInfo = literal_eval(cleaned_str)
|
||||
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.INPUT_FAILURE +
|
||||
Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.INPUT_FINISHED)
|
||||
|
||||
|
||||
def get_approximately_align_info(self):
|
||||
try:
|
||||
df = read_csv(Config["Path"]["Input_Approximately_Align"])
|
||||
pos = df["pos"].values[-1]
|
||||
ApplyFrequency = df["ApplyFrequency"].values[-1]
|
||||
self.TimeBiasSecond = pos / ApplyFrequency
|
||||
self.actualBCGFreq = df["estimate_freq"].values[-1] * Config["BCGFreq"]
|
||||
return Result().success(info=Constants.INPUT_FINISHED)
|
||||
|
||||
except Exception as e:
|
||||
self.TimeBiasSecond = 0
|
||||
self.actualBCGFreq = Config["BCGFreq"]
|
||||
traceback.print_exc()
|
||||
return Result().failure(info=Constants.INPUT_FAILURE
|
||||
+ Constants.FAILURE_REASON["Get_Approximately_Align_Info_Exception"]
|
||||
+ "\n" + format_exc())
|
||||
|
||||
def resample_BCG(self):
|
||||
try:
|
||||
for key in self.raw.keys():
|
||||
if Config["ChannelInput"][key].startswith("OrgBCG:"):
|
||||
# data = self.raw[key]
|
||||
# n_samples = len(data)
|
||||
# duration = n_samples / self.actualBCGFreq
|
||||
#
|
||||
# t_old = np.linspace(0, duration, n_samples, endpoint=False)
|
||||
# n_new = int(np.round(duration * Config["BCGFreq"]))
|
||||
# t_new = np.linspace(0, duration, n_new, endpoint=False)
|
||||
# self.raw[key] = np.interp(t_new, t_old, data)
|
||||
resample_signal = soxr.resample(
|
||||
x=self.raw[key].astype(np.float64),
|
||||
in_rate=self.actualBCGFreq,
|
||||
out_rate=Config["BCGFreq"],
|
||||
quality='VHQ'
|
||||
)
|
||||
print(f"Resampled BCG from {self.actualBCGFreq}Hz to {Config['BCGFreq']}Hz, original length: {len(self.raw[key])}, new length: {len(resample_signal)}")
|
||||
self.raw[key] = resample_signal.astype(self.raw[key].dtype)
|
||||
|
||||
self.TimeBiasSecond = int(self.TimeBiasSecond * (self.actualBCGFreq / Config["BCGFreq"]))
|
||||
|
||||
|
||||
|
||||
return Result().success(info=Constants.CUT_PAIR_FILE_ROUGH_RESAMPLE_BCG_FINISHED)
|
||||
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
print(e)
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_ROUGH_RESAMPLE_BCG_FAILURE +
|
||||
Constants.FAILURE_REASON["Resample_BCG_Exception"] + "\n" + format_exc())
|
||||
|
||||
|
||||
def calc_approximately_align_info(self, OrgBCGShift=0):
|
||||
try:
|
||||
# 获取BCG长度
|
||||
BCG_freq = Config["BCGFreq"]
|
||||
BCG_second = len(self.raw["OrgBCG"]) // BCG_freq
|
||||
|
||||
# 计算ECG长度
|
||||
ECG_freq = Config["ECGFreq"]
|
||||
ECG_second = len(self.raw["ECG"]) // ECG_freq
|
||||
|
||||
|
||||
pos = self.TimeBiasSecond
|
||||
|
||||
# 如果pos<0,表示BCG信号比ECG信号提前,需要在开头去除掉一部分BCG信号
|
||||
if pos < 0:
|
||||
front_BCG = ceil(-pos) - OrgBCGShift
|
||||
front_ECG = 0
|
||||
else:
|
||||
front_BCG = 0
|
||||
front_ECG = ceil(pos) + OrgBCGShift
|
||||
|
||||
# 计算剩余长度
|
||||
remain_BCG_second = BCG_second - front_BCG
|
||||
remain_ECG_second = ECG_second - front_ECG
|
||||
remain_second = min(remain_BCG_second, remain_ECG_second)
|
||||
back_BCG = front_BCG + remain_second - 1
|
||||
back_ECG = front_ECG + remain_second - 1
|
||||
|
||||
self.alignInfo = {
|
||||
"cut_index": {
|
||||
"front_BCG": front_BCG * BCG_freq,
|
||||
"back_BCG": back_BCG * BCG_freq,
|
||||
"front_ECG": front_ECG * ECG_freq,
|
||||
"back_ECG": back_ECG * ECG_freq,
|
||||
}
|
||||
}
|
||||
return Result().success(info=Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_CALC_FINISHED)
|
||||
|
||||
|
||||
except Exception as e:
|
||||
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 delete_rough_cut_file(self):
|
||||
# 在保存路径中删除RoughCut文件
|
||||
try:
|
||||
for key in Config["ChannelInput"].keys():
|
||||
if Config["ChannelInput"][key].startswith("OrgBCG:"):
|
||||
file_path = Path(Config["Path"]["SaveOrgBCGFolder"]).glob(f"{Config['ChannelSave'][key][len('OrgBCG:'):]}*{Config['EndWith'][key]}")
|
||||
for file in file_path:
|
||||
file.unlink()
|
||||
if Config["ChannelInput"][key].startswith("PSG:"):
|
||||
file_path = Path(Config["Path"]["SavePSGFolder"]).glob(f"{Config['ChannelSave'][key][len('PSG:'):]}*{Config['EndWith'][key]}")
|
||||
for file in file_path:
|
||||
file.unlink()
|
||||
return Result().success(info=Constants.CUT_PAIR_FILE_DELETE_ROUGH_CUT_FILE_FINISHED)
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_DELETE_ROUGH_CUT_FILE_FAILURE +
|
||||
Constants.FAILURE_REASON["Delete_Rough_Cut_File_Exception"] + "\n" + format_exc())
|
||||
|
||||
def cut_data(self):
|
||||
try:
|
||||
|
||||
for key, raw in self.raw.items():
|
||||
if Config["ChannelInput"][key].startswith("PSG:"):
|
||||
# 转换切割点
|
||||
ECG_freq = Config["ECGFreq"]
|
||||
raw_freq = self.freq[key]
|
||||
duration_second = ((self.alignInfo["cut_index"]["back_ECG"] - self.alignInfo["cut_index"]["front_ECG"]) // ECG_freq) + 1
|
||||
start_index_cut = floor(self.alignInfo["cut_index"]["front_ECG"] * (raw_freq / ECG_freq))
|
||||
end_index_cut = start_index_cut + (duration_second * raw_freq)
|
||||
|
||||
try:
|
||||
# 切割信号
|
||||
self.raw[key] = self.raw[key][start_index_cut:end_index_cut]
|
||||
except Exception:
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_CUT_DATA_FAILURE +
|
||||
Constants.FAILURE_REASON["Cut_Data_Length_not_Correct"])
|
||||
elif Config["ChannelInput"][key].startswith("OrgBCG:"):
|
||||
# 转换切割点
|
||||
BCG_freq = Config["BCGFreq"]
|
||||
raw_freq = self.freq[key]
|
||||
duration_second = ((self.alignInfo["cut_index"]["back_BCG"] - self.alignInfo["cut_index"]["front_BCG"]) // BCG_freq) + 1
|
||||
start_index_cut = floor(self.alignInfo["cut_index"]["front_BCG"] * (raw_freq / BCG_freq))
|
||||
end_index_cut = start_index_cut + (duration_second * raw_freq)
|
||||
|
||||
try:
|
||||
# 切割信号
|
||||
self.raw[key] = self.raw[key][start_index_cut:end_index_cut]
|
||||
except Exception:
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_CUT_DATA_FAILURE +
|
||||
Constants.FAILURE_REASON["Cut_Data_Length_not_Correct"])
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_CUT_DATA_FAILURE +
|
||||
Constants.FAILURE_REASON["Cut_Data_Exception"] + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.CUT_PAIR_FILE_CUT_DATA_FINISHED)
|
||||
|
||||
def align_label(self):
|
||||
try:
|
||||
# 读取SA标签
|
||||
self.SALabel = self.SALabel.loc[:, ~self.SALabel.columns.str.contains("^Unnamed")]
|
||||
self.SALabel = self.SALabel[self.SALabel["Event type"].isin(Params.CUT_PAIR_FILE_SALABEL_EVENT)]
|
||||
self.SALabel["Duration"] = self.SALabel["Duration"].astype(str)
|
||||
self.SALabel["Duration"] = self.SALabel["Duration"].str.replace(r' \(.*?\)', '', regex=True)
|
||||
except Exception:
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_ALIGN_LABEL_FAILURE +
|
||||
Constants.FAILURE_REASON["Align_Label_SALabel_Format_not_Correct"])
|
||||
|
||||
try:
|
||||
# 获取记录开始时间
|
||||
start_time = str(self.startTime[0]).split(" ")[1]
|
||||
start_time = Data.get_time_to_seconds(start_time)
|
||||
ECG_freq = Config["ECGFreq"]
|
||||
|
||||
# 计算起始时间秒数和终止时间秒数
|
||||
self.SALabel["Start"] = (self.SALabel["Time"].apply(self.get_time_to_seconds) - start_time).apply(
|
||||
lambda x: x + 24 * 3600 if x < 0 else x).astype(int)
|
||||
self.SALabel["End"] = self.SALabel["Start"] + self.SALabel["Duration"].astype(float).round(0).astype(int)
|
||||
|
||||
# 标签映射
|
||||
ECG_length = self.alignInfo["cut_index"]["back_ECG"] - self.alignInfo["cut_index"]["front_ECG"]
|
||||
self.SALabel["Start"] = self.SALabel["Start"] - round((self.alignInfo["cut_index"]["front_ECG"] / ECG_freq))
|
||||
self.SALabel["End"] = self.SALabel["End"] - round((self.alignInfo["cut_index"]["front_ECG"] / ECG_freq))
|
||||
self.SALabel = self.SALabel[self.SALabel["End"] >= 0]
|
||||
self.SALabel.loc[self.SALabel["Start"] < 0, "Start"] = 0
|
||||
self.SALabel = self.SALabel[self.SALabel["Start"] < ECG_length]
|
||||
self.SALabel.loc[self.SALabel["End"] >= ECG_length, "End"] = ECG_length - 1
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.CUT_PAIR_FILE_ALIGN_LABEL_FAILURE +
|
||||
Constants.FAILURE_REASON["Align_Label_Exception"] + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.CUT_PAIR_FILE_ALIGN_LABEL_FINISHED)
|
||||
|
||||
def save(self):
|
||||
for raw in self.raw.values():
|
||||
if len(raw) == 0:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE +
|
||||
Constants.FAILURE_REASON["Data_not_Exist"])
|
||||
|
||||
try:
|
||||
for key, raw in self.raw.items():
|
||||
if Config["ChannelInput"][key].startswith("PSG:"):
|
||||
# print(f"Saving PSG channel: {key} to {Config['Path']['SavePSGFolder']} / {Config['ChannelSave'][key] + str(self.freq[key]) + Config['EndWith'][key]}")
|
||||
DataFrame(raw.reshape(-1)).to_csv(Path(Config["Path"]["SavePSGFolder"]) / Path((Config["ChannelSave"][key][len("PSG:"):] + str(self.freq[key]) + Config["EndWith"][key])),
|
||||
index=False, header=False)
|
||||
elif Config["ChannelInput"][key].startswith("OrgBCG:"):
|
||||
# print(f"Saving OrgBCG channel: {key} to {Config['Path']['SaveOrgBCGFolder']} / {Config['ChannelSave'][key] + str(self.freq[key]) + Config['EndWith'][key]}")
|
||||
DataFrame(raw.reshape(-1)).to_csv(Path(Config["Path"]["SaveOrgBCGFolder"]) / Path((Config["ChannelSave"][key][len("OrgBCG:"):] + str(self.freq[key]) + Config["EndWith"][key])),
|
||||
index=False, header=False)
|
||||
# 重排index,从1开始,并给index命名
|
||||
self.SALabel.sort_values(by=["Start"], inplace=True)
|
||||
self.SALabel.reset_index(drop=True, inplace=True)
|
||||
self.SALabel.index = self.SALabel.index + 1
|
||||
self.SALabel.index.name = "Index"
|
||||
self.SALabel.to_csv(Path(Config["Path"]["SavePSGFolder"]) / Path((Config["LabelSave"]["SA Label"] + Config["EndWith"]["SA Label"])),
|
||||
encoding="gbk")
|
||||
except PermissionError as e:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Save_Permission_Denied"])
|
||||
except FileNotFoundError as e:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Save_File_Not_Found"])
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE +
|
||||
Constants.FAILURE_REASON["Save_Exception"] + "\n" + format_exc())
|
||||
|
||||
return Result().success(info=Constants.SAVE_FINISHED)
|
||||
|
||||
@staticmethod
|
||||
def get_time_to_seconds(time_str):
|
||||
h, m, s = map(int, time_str.split(":"))
|
||||
return h * 3600 + m * 60 + s
|
||||
@ -338,7 +338,8 @@ class MainWindow_detect_Jpeak(QMainWindow):
|
||||
# 预测峰值
|
||||
PublicFunc.progressbar_update(self, 2, 3, Constants.DETECT_JPEAK_PREDICTING_PEAK, 10)
|
||||
self.model.selected_model = Config["DetectMethod"]
|
||||
result = self.data.predict_Jpeak(self.model)
|
||||
scale = self.ui.spinBox_scaleValue.value() if self.ui.checkBox_scaleEnable.isChecked() else 0
|
||||
result = self.data.predict_Jpeak(self.model, batch_size=int(self.ui.comboBox_batchSize.currentText()), scale=scale)
|
||||
if not result.status:
|
||||
PublicFunc.text_output(self.ui, "(2/3)" + result.info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.MSGBOX_TYPE_ERROR)
|
||||
@ -469,7 +470,7 @@ class Data:
|
||||
return Result().failure(info=Constants.PREPROCESS_FAILURE +
|
||||
Constants.FAILURE_REASON["Preprocess_Exception"] + "\n" + format_exc())
|
||||
|
||||
def predict_Jpeak(self, model):
|
||||
def predict_Jpeak(self, model, batch_size=0, scale=0):
|
||||
if not (Path(model.model_folder_path) / Path(model.selected_model)).exists():
|
||||
return Result().failure(info=Constants.DETECT_JPEAK_PREDICT_FAILURE +
|
||||
Constants.FAILURE_REASON["Model_File_Not_Exist"])
|
||||
@ -489,7 +490,9 @@ class Data:
|
||||
Config["IntervalHigh"],
|
||||
Config["IntervalLow"],
|
||||
Config["PeaksValue"],
|
||||
Config["UseCPU"])
|
||||
Config["UseCPU"],
|
||||
batch_size,
|
||||
scale)
|
||||
except Exception as e:
|
||||
return Result().failure(info=Constants.DETECT_JPEAK_PREDICT_FAILURE +
|
||||
Constants.FAILURE_REASON["Predict_Exception"] + "\n" + format_exc())
|
||||
|
||||
@ -36,7 +36,8 @@ ButtonState = {
|
||||
"pushButton_save": False,
|
||||
"pushButton_prev_move": False,
|
||||
"pushButton_pause": False,
|
||||
"pushButton_next_move": False
|
||||
"pushButton_next_move": False,
|
||||
"pushButton_update_state": False
|
||||
},
|
||||
"Current": {
|
||||
"pushButton_input_setting": True,
|
||||
@ -44,7 +45,8 @@ ButtonState = {
|
||||
"pushButton_save": False,
|
||||
"pushButton_prev_move": False,
|
||||
"pushButton_pause": False,
|
||||
"pushButton_next_move": False
|
||||
"pushButton_next_move": False,
|
||||
"pushButton_update_state": False
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,6 +259,9 @@ class MainWindow_label_check(QMainWindow):
|
||||
self.point_peak_corrected = None
|
||||
self.annotation_tableWidget = None
|
||||
|
||||
self.move_state = None
|
||||
self.last_move_state = None
|
||||
|
||||
self.ui.textBrowser_info.setStyleSheet("QTextBrowser { background-color: rgb(255, 255, 200); }")
|
||||
PublicFunc.__styleAllButton__(self, ButtonState)
|
||||
|
||||
@ -332,6 +337,7 @@ class MainWindow_label_check(QMainWindow):
|
||||
self.ui.pushButton_prev_move.clicked.connect(self.__slot_btn_move__)
|
||||
self.ui.pushButton_pause.clicked.connect(self.__slot_btn_move__)
|
||||
self.ui.pushButton_next_move.clicked.connect(self.__slot_btn_move__)
|
||||
self.ui.pushButton_update_state.clicked.connect(self.__update_state__)
|
||||
self.ui.radioButton_move_preset_1.toggled.connect(self.__change_autoplay_args__)
|
||||
self.ui.radioButton_move_preset_2.toggled.connect(self.__change_autoplay_args__)
|
||||
self.ui.radioButton_move_preset_3.toggled.connect(self.__change_autoplay_args__)
|
||||
@ -347,6 +353,20 @@ class MainWindow_label_check(QMainWindow):
|
||||
self.ui.spinBox_maxRange.editingFinished.connect(self.__update_config__)
|
||||
self.ui.spinBox_moveSpeed.editingFinished.connect(self.__update_config__)
|
||||
|
||||
self.ui.pushButton_prev_move.setShortcut(
|
||||
QCoreApplication.translate("MainWindow", Params.LABEL_CHECK_BTN_PREV_MOVE_SHORTCUT_KEY))
|
||||
self.ui.pushButton_next_move.setShortcut(
|
||||
QCoreApplication.translate("MainWindow", Params.LABEL_CHECK_BTN_NEXT_MOVE_SHORTCUT_KEY))
|
||||
self.ui.pushButton_pause.setShortcut(
|
||||
QCoreApplication.translate("MainWindow", Params.LABEL_CHECK_BTN_PAUSE_SHORTCUT_KEY)
|
||||
)
|
||||
self.ui.pushButton_update_state.setShortcut(
|
||||
QCoreApplication.translate("MainWindow", Params.LABEL_CHECK_BTN_UPDATE_STATE_SHORTCUT_KEY)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@overrides
|
||||
def closeEvent(self, event):
|
||||
reply = QMessageBox.question(self, '确认', '确认退出吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
||||
@ -576,6 +596,8 @@ class MainWindow_label_check(QMainWindow):
|
||||
ButtonState["Current"]["pushButton_prev_move"] = True
|
||||
ButtonState["Current"]["pushButton_next_move"] = True
|
||||
ButtonState["Current"]["pushButton_pause"] = True
|
||||
ButtonState["Current"]["pushButton_update_state"] = True
|
||||
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
def __slot_btn_save__(self):
|
||||
@ -595,6 +617,20 @@ class MainWindow_label_check(QMainWindow):
|
||||
PublicFunc.msgbox_output(self, result.info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
def __update_state__(self):
|
||||
if self.move_state == "moving":
|
||||
self.ui.pushButton_pause.click()
|
||||
self.move_state = "pause"
|
||||
else:
|
||||
if self.last_move_state == "prev":
|
||||
self.ui.pushButton_prev_move.click()
|
||||
elif self.last_move_state == "next":
|
||||
self.ui.pushButton_next_move.click()
|
||||
else:
|
||||
self.ui.pushButton_next_move.click()
|
||||
self.move_state = "moving"
|
||||
|
||||
|
||||
def __slot_btn_move__(self):
|
||||
if self.data is None:
|
||||
return
|
||||
@ -602,6 +638,8 @@ class MainWindow_label_check(QMainWindow):
|
||||
sender = self.sender()
|
||||
|
||||
if sender == self.ui.pushButton_prev_move:
|
||||
self.last_move_state = "prev"
|
||||
self.move_state = "moving"
|
||||
Config["AutoplayArgs"]["AutoplayMode"] = "prev"
|
||||
self.autoplay_xlim_start = int(self.ax0.get_xlim()[1] - Config["AutoplayArgs"]["MaxRange"])
|
||||
self.autoplay_xlim_end = int(self.ax0.get_xlim()[1])
|
||||
@ -613,6 +651,8 @@ class MainWindow_label_check(QMainWindow):
|
||||
self.timer_autoplay.start(Config["AutoplayArgs"]["MoveSpeed"])
|
||||
PublicFunc.text_output(self.ui, Constants.LABEL_CHECK_PREV_MOVE, Constants.TIPS_TYPE_INFO)
|
||||
elif sender == self.ui.pushButton_next_move:
|
||||
self.last_move_state = "next"
|
||||
self.move_state = "moving"
|
||||
Config["AutoplayArgs"]["AutoplayMode"] = "next"
|
||||
self.autoplay_xlim_start = int(self.ax0.get_xlim()[0])
|
||||
self.autoplay_xlim_end = int(self.ax0.get_xlim()[0] + Config["AutoplayArgs"]["MaxRange"])
|
||||
|
||||
@ -16,7 +16,7 @@ from func.Module_detect_Jpeak import MainWindow_detect_Jpeak
|
||||
from func.Module_detect_Rpeak import MainWindow_detect_Rpeak
|
||||
from func.Module_label_check import MainWindow_label_check
|
||||
from func.Module_precisely_align import MainWindow_precisely_align
|
||||
from func.Module_cut_PSG import MainWindow_cut_PSG
|
||||
from func.Module_cut_pair_file import MainWindow_cut_PAIR_FILE
|
||||
from func.Module_artifact_label import MainWindow_artifact_label
|
||||
from func.Module_bcg_quality_label import MainWindow_bcg_quality_label
|
||||
from func.Module_resp_quality_label import MainWindow_resp_quality_label
|
||||
@ -266,7 +266,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
self.check_save_path_and_mkdir(root_path, sampID)
|
||||
|
||||
def __slot_btn_cut_PSG__(self):
|
||||
self.cut_PSG = MainWindow_cut_PSG()
|
||||
self.cut_PSG = MainWindow_cut_PAIR_FILE()
|
||||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||||
sampID = self.ui.comboBox_sampID.currentText()
|
||||
if not self.check_root_path():
|
||||
|
||||
@ -9,12 +9,13 @@ from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication, QButtonGro
|
||||
from matplotlib import gridspec, patches
|
||||
from matplotlib.backends.backend_qt import NavigationToolbar2QT
|
||||
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
|
||||
from matplotlib.ticker import FuncFormatter, ScalarFormatter
|
||||
from numpy import (diff, where, correlate, corrcoef, searchsorted, sum as np_sum, max as np_max, min as np_min, arange,
|
||||
array,
|
||||
append, delete, abs as np_abs, argmin as np_argmin, argmax as np_argmax, asarray)
|
||||
from overrides import overrides
|
||||
from pandas import read_csv, DataFrame
|
||||
# from resampy import resample
|
||||
from resampy import resample as rspy_resample
|
||||
|
||||
from scipy.signal import find_peaks, resample as ss_resample
|
||||
from yaml import dump, load, FullLoader
|
||||
@ -38,7 +39,10 @@ ButtonState = {
|
||||
"pushButton_calculate_correlation": False,
|
||||
"pushButton_correlation_align": False,
|
||||
"pushButton_view_align": False,
|
||||
"pushButton_save": False
|
||||
"pushButton_save": False,
|
||||
"checkBox_sync_xlim": False,
|
||||
"pushButton_getPos": False,
|
||||
"pushButton_resetPos": False
|
||||
},
|
||||
"Current": {
|
||||
"pushButton_input_setting": True,
|
||||
@ -46,7 +50,10 @@ ButtonState = {
|
||||
"pushButton_calculate_correlation": False,
|
||||
"pushButton_correlation_align": False,
|
||||
"pushButton_view_align": False,
|
||||
"pushButton_save": False
|
||||
"pushButton_save": False,
|
||||
"checkBox_sync_xlim": False,
|
||||
"pushButton_getPos": False,
|
||||
"pushButton_resetPos": False
|
||||
},
|
||||
"Statue_1": {
|
||||
"pushButton_input_setting": False,
|
||||
@ -54,7 +61,10 @@ ButtonState = {
|
||||
"pushButton_calculate_correlation": True,
|
||||
"pushButton_correlation_align": False,
|
||||
"pushButton_view_align": False,
|
||||
"pushButton_save": False
|
||||
"pushButton_save": False,
|
||||
"checkBox_sync_xlim": True,
|
||||
"pushButton_getPos": False,
|
||||
"pushButton_resetPos": False
|
||||
},
|
||||
"Statue_2": {
|
||||
"pushButton_input_setting": False,
|
||||
@ -62,7 +72,10 @@ ButtonState = {
|
||||
"pushButton_calculate_correlation": True,
|
||||
"pushButton_correlation_align": True,
|
||||
"pushButton_view_align": False,
|
||||
"pushButton_save": False
|
||||
"pushButton_save": False,
|
||||
"checkBox_sync_xlim": False,
|
||||
"pushButton_getPos": False,
|
||||
"pushButton_resetPos": False
|
||||
},
|
||||
"Statue_3": {
|
||||
"pushButton_input_setting": False,
|
||||
@ -70,7 +83,10 @@ ButtonState = {
|
||||
"pushButton_calculate_correlation": False,
|
||||
"pushButton_correlation_align": False,
|
||||
"pushButton_view_align": True,
|
||||
"pushButton_save": False
|
||||
"pushButton_save": False,
|
||||
"checkBox_sync_xlim": False,
|
||||
"pushButton_getPos": False,
|
||||
"pushButton_resetPos": False
|
||||
},
|
||||
"Statue_4": {
|
||||
"pushButton_input_setting": False,
|
||||
@ -78,7 +94,10 @@ ButtonState = {
|
||||
"pushButton_calculate_correlation": False,
|
||||
"pushButton_correlation_align": False,
|
||||
"pushButton_view_align": False,
|
||||
"pushButton_save": True
|
||||
"pushButton_save": True,
|
||||
"checkBox_sync_xlim": False,
|
||||
"pushButton_getPos": False,
|
||||
"pushButton_resetPos": False
|
||||
},
|
||||
}
|
||||
|
||||
@ -393,8 +412,12 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
self.ui.pushButton_correlation_align.clicked.connect(self.__slot_btn_correlation_align__)
|
||||
self.ui.pushButton_view_align.clicked.connect(self.__slot_btn_view_align__)
|
||||
self.ui.pushButton_save.clicked.connect(self.__slot_btn_save__)
|
||||
self.ui.pushButton_getPos.clicked.connect(self.__get_current_pos__)
|
||||
self.ui.pushButton_resetPos.clicked.connect(self.__reset_pos__)
|
||||
self.canvas.mpl_connect('pick_event', self.on_pick)
|
||||
|
||||
self.ui.checkBox_sync_xlim.checkStateChanged.connect(self.__checkBox_sync_xlim_changed__)
|
||||
|
||||
self.ui.spinBox_BCG_front_JJIV_1.editingFinished.connect(self.__update_coordinate__)
|
||||
self.ui.spinBox_BCG_front_JJIV_2.editingFinished.connect(self.__update_coordinate__)
|
||||
self.ui.spinBox_BCG_back_JJIV_1.editingFinished.connect(self.__update_coordinate__)
|
||||
@ -404,6 +427,8 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
self.ui.spinBox_ECG_back_RRIV_1.editingFinished.connect(self.__update_coordinate__)
|
||||
self.ui.spinBox_ECG_back_RRIV_2.editingFinished.connect(self.__update_coordinate__)
|
||||
|
||||
self.ui.label_sampno.setText(str(self.sampID))
|
||||
|
||||
@overrides
|
||||
def closeEvent(self, event):
|
||||
reply = QMessageBox.question(self, '确认', '确认退出吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
||||
@ -470,39 +495,105 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
|
||||
sender = self.sender()
|
||||
|
||||
def offset_formatter(x, pos):
|
||||
if self.data.BCG_early:
|
||||
return f"{int(x + self.data.approximately_align_pos)}"
|
||||
else:
|
||||
return f"{int(x - self.data.approximately_align_pos)}"
|
||||
|
||||
|
||||
|
||||
if sender == self.ui.pushButton_input:
|
||||
self.gs = gridspec.GridSpec(2, 1, height_ratios=[1, 1])
|
||||
self.fig.subplots_adjust(top=0.95, bottom=0.05, right=0.98, left=0.05, hspace=0.15, wspace=0)
|
||||
self.ax0 = self.fig.add_subplot(self.gs[0])
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax1 = self.fig.add_subplot(self.gs[1], sharex=self.ax0, sharey=self.ax0)
|
||||
# self.ax0.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
self.ax1 = self.fig.add_subplot(self.gs[1], sharey=self.ax0)
|
||||
self.ax1.grid(True)
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
# self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
Jpeak = self.data.Jpeak[:-2]
|
||||
Rpeak = self.data.Rpeak[:-2]
|
||||
self.ax0.set_title("JJIV")
|
||||
self.ax1.set_title("RRIV")
|
||||
|
||||
self._syncing_xlim_change = False
|
||||
|
||||
def on_ax0_xlim_changed(ax):
|
||||
if self.ui.checkBox_sync_xlim.isChecked() is False:
|
||||
return
|
||||
if self._syncing_xlim_change:
|
||||
return
|
||||
if ax is self.ax0:
|
||||
self._syncing_xlim_change = True
|
||||
x0, x1 = ax.get_xlim()
|
||||
self.ax1.set_xlim(x0, x1)
|
||||
self._syncing_xlim_change = False
|
||||
|
||||
def on_ax1_xlim_changed(ax):
|
||||
if self.ui.checkBox_sync_xlim.isChecked() is False:
|
||||
return
|
||||
if self._syncing_xlim_change:
|
||||
return
|
||||
if ax is self.ax1:
|
||||
self._syncing_xlim_change = True
|
||||
x0, x1 = ax.get_xlim()
|
||||
self.ax0.set_xlim(x0, x1)
|
||||
self._syncing_xlim_change = False
|
||||
|
||||
if self.data.BCG_early:
|
||||
Jpeak = Jpeak - self.data.approximately_align_pos
|
||||
else:
|
||||
Jpeak = Jpeak + self.data.approximately_align_pos
|
||||
|
||||
# if self.data.BCG_early is True:
|
||||
# self.ax0.stem(Jpeak, plot_element["JJIVs"],
|
||||
# markerfmt="C0.", linefmt=Constants.PLOT_COLOR_GREEN,
|
||||
# label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
|
||||
# self.ax1.stem(Rpeak, plot_element["RRIVs"],
|
||||
# markerfmt="C0.", linefmt=Constants.PLOT_COLOR_ORANGE,
|
||||
# label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RRIV)
|
||||
# self.ax0.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--",
|
||||
# label="Start Line")
|
||||
# self.ax1.axvline(x=0, color=Constants.PLOT_COLOR_BLACK, linestyle="--", label="Start Line")
|
||||
|
||||
# elif self.data.BCG_early is False:
|
||||
# Jpeak = Jpeak + self.data.approximately_align_pos
|
||||
|
||||
# self.ax0.stem(Jpeak, plot_element["JJIVs"],
|
||||
# markerfmt="C0.", linefmt=Constants.PLOT_COLOR_GREEN,
|
||||
# label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
|
||||
# self.ax1.stem(Rpeak, plot_element["RRIVs"],
|
||||
# markerfmt="C0.", linefmt=Constants.PLOT_COLOR_ORANGE,
|
||||
# label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RRIV)
|
||||
# self.ax0.axvline(x=0, color=Constants.PLOT_COLOR_BLACK, linestyle="--", label="Start Line")
|
||||
# self.ax1.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--",
|
||||
# label="Start Line")
|
||||
# else:
|
||||
# self.ax0.stem(Jpeak, plot_element["JJIVs"],
|
||||
# markerfmt="C0.", linefmt=Constants.PLOT_COLOR_GREEN,
|
||||
# label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
|
||||
# self.ax1.stem(Rpeak, plot_element["RRIVs"],
|
||||
# markerfmt="C0.", linefmt=Constants.PLOT_COLOR_ORANGE,
|
||||
# label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RRIV)
|
||||
# self.ax0.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--",
|
||||
# label="Start Line")
|
||||
# self.ax1.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--",
|
||||
# label="Start Line")
|
||||
self.ax0.stem(Jpeak, plot_element["JJIVs"],
|
||||
markerfmt="C0.", linefmt=Constants.PLOT_COLOR_GREEN,
|
||||
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_JJIV)
|
||||
self.ax1.set_title("RRIV")
|
||||
self.ax0.xaxis.set_major_formatter(FuncFormatter(offset_formatter))
|
||||
|
||||
self.ax1.stem(Rpeak, plot_element["RRIVs"],
|
||||
markerfmt="C0.", linefmt=Constants.PLOT_COLOR_ORANGE,
|
||||
label=Constants.PRECISELY_ALIGN_PLOT_LABEL_RRIV)
|
||||
if self.data.BCG_early is True:
|
||||
self.ax0.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--",
|
||||
label="Start Line")
|
||||
self.ax1.axvline(x=0, color=Constants.PLOT_COLOR_BLACK, linestyle="--", label="Start Line")
|
||||
elif self.data.BCG_early is False:
|
||||
self.ax0.axvline(x=0, color=Constants.PLOT_COLOR_BLACK, linestyle="--", label="Start Line")
|
||||
self.ax1.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--",
|
||||
label="Start Line")
|
||||
else:
|
||||
self.ax0.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--",
|
||||
label="Start Line")
|
||||
self.ax1.axvline(x=self.data.approximately_align_pos, color=Constants.PLOT_COLOR_BLACK, linestyle="--",
|
||||
label="Start Line")
|
||||
self.ax1.xaxis.set_major_formatter(Params.FORMATTER)
|
||||
|
||||
self.ax0.callbacks.connect('xlim_changed', on_ax0_xlim_changed)
|
||||
self.ax1.callbacks.connect('xlim_changed', on_ax1_xlim_changed)
|
||||
|
||||
|
||||
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
|
||||
self.ax1.legend(loc=Constants.PLOT_UPPER_RIGHT)
|
||||
@ -632,6 +723,55 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
self.canvas.draw()
|
||||
return Result().failure(info=Constants.DRAW_FAILURE)
|
||||
|
||||
def __checkBox_sync_xlim_changed__(self):
|
||||
if not self.ui.checkBox_sync_xlim.isChecked():
|
||||
self.ui.pushButton_getPos.setEnabled(True)
|
||||
self.ui.pushButton_resetPos.setEnabled(True)
|
||||
else:
|
||||
self.ui.pushButton_getPos.setEnabled(False)
|
||||
self.ui.pushButton_resetPos.setEnabled(False)
|
||||
|
||||
def __get_current_pos__(self):
|
||||
if self.ui.checkBox_sync_xlim.isChecked():
|
||||
return
|
||||
# 获取当前两子图的x轴起始点
|
||||
ax0_x0, _ = self.ax0.get_xlim()
|
||||
ax1_x0, _ = self.ax1.get_xlim()
|
||||
# 获取ax0的trick位置
|
||||
# if self.data.BCG_early:
|
||||
# ax1_x0 += self.data.approximately_align_pos
|
||||
# else:
|
||||
# ax0_x0 -= self.data.approximately_align_pos
|
||||
|
||||
print(ax0_x0, ax1_x0)
|
||||
|
||||
actual_pos = -1 * self.data.approximately_align_pos if self.data.BCG_early else self.data.approximately_align_pos
|
||||
actual_ax0_x0 = ax0_x0 - actual_pos
|
||||
new_pos = actual_ax0_x0 - ax1_x0
|
||||
print(actual_ax0_x0, ax1_x0)
|
||||
if new_pos > 0:
|
||||
self.data.BCG_early = True
|
||||
else:
|
||||
self.data.BCG_early = False
|
||||
|
||||
self.data.approximately_align_pos = abs(new_pos)
|
||||
print(self.data.BCG_early, self.data.approximately_align_pos)
|
||||
|
||||
self.ui.label_pos.setText(str(int(self.data.approximately_align_pos) * (-1 if self.data.BCG_early else 1)))
|
||||
|
||||
self.ui.pushButton_input.click()
|
||||
|
||||
|
||||
def __reset_pos__(self):
|
||||
if self.data.TimeBiasSecond > 0:
|
||||
self.data.BCG_early = True
|
||||
else:
|
||||
self.data.BCG_early = False
|
||||
self.data.approximately_align_pos = abs(self.data.TimeBiasSecond)
|
||||
self.ui.label_pos.setText(str(int(self.data.approximately_align_pos) * (-1 if self.data.BCG_early else 1)))
|
||||
|
||||
|
||||
|
||||
def __update_info__(self):
|
||||
self.ui.spinBox_BCG_front_JJIV_1.setValue(Config["IV_Coordinate"]["BCG_front_1"])
|
||||
self.ui.spinBox_BCG_front_JJIV_2.setValue(Config["IV_Coordinate"]["BCG_front_2"])
|
||||
@ -711,6 +851,9 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
action.setEnabled(True)
|
||||
ButtonState["Current"].update(ButtonState["Statue_1"].copy())
|
||||
PublicFunc.finish_operation(self, ButtonState)
|
||||
|
||||
self.ui.label_pos.setText(str(int(self.data.approximately_align_pos) * (-1 if self.data.BCG_early else 1)))
|
||||
|
||||
self.ui.pushButton_input.clicked.disconnect()
|
||||
self.ui.pushButton_input.clicked.connect(self.__slot_btn_repick__)
|
||||
self.ui.pushButton_input.setText("重新选取")
|
||||
@ -1392,6 +1535,14 @@ class MainWindow_precisely_align(QMainWindow):
|
||||
elif rect_right < 0:
|
||||
rect_left = 0
|
||||
rect_right = 0
|
||||
|
||||
if self.data.BCG_early:
|
||||
# 如果是提前BCG模式,J峰位置需要加上offset
|
||||
rect_left += self.data.approximately_align_pos
|
||||
rect_right += self.data.approximately_align_pos
|
||||
else:
|
||||
rect_left -= self.data.approximately_align_pos
|
||||
rect_right -= self.data.approximately_align_pos
|
||||
indices = where((self.data.Jpeak[:-2] >= rect_left) & (self.data.Jpeak[:-2] <= rect_right))[0]
|
||||
if indices is None or len(indices) <= 0:
|
||||
if self.ui.radioButton_BCG_front.isChecked():
|
||||
@ -1622,6 +1773,7 @@ class Data:
|
||||
self.approximately_align_slope = None
|
||||
self.approximately_align_intercept = None
|
||||
self.BCG_early = None
|
||||
self.TimeBiasSecond = None
|
||||
|
||||
self.res_orgBcg = None
|
||||
self.res_BCG = None
|
||||
@ -1660,6 +1812,13 @@ class Data:
|
||||
if Path(Config["Path"]["Input_Approximately_Align"]).is_file():
|
||||
Config["Path"]["Input_Approximately_Align"] = str(Path(Config["Path"]["Input_Approximately_Align"]).parent)
|
||||
|
||||
result = PublicFunc.get_machine_start_time_bias(Config["Path"]["Input_ECG"], Config["Path"]["Input_OrgBCG"])
|
||||
if result.status:
|
||||
self.TimeBiasSecond = result.data["time_bias"] * Config["InputConfig"]["UseFreq"]
|
||||
else:
|
||||
self.TimeBiasSecond = 0
|
||||
|
||||
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_OrgBCG"], Filename.ORGBCG_RAW, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_OrgBCG"] = result.data["path"]
|
||||
@ -1674,7 +1833,7 @@ class Data:
|
||||
Filename.PRECISELY_ALIGN_INFO + Params.ENDSWITH_TXT))
|
||||
Config["Path"]["Save_OrgBCG"] = str(
|
||||
Path(Config["Path"]["Save_OrgBCG"]) / Path(
|
||||
Filename.ORGBCG_SYNC + str(Config["InputConfig"]["orgBcgFreq"]) + Params.ENDSWITH_TXT))
|
||||
Filename.ORGBCG_SYNC + str(Config["InputConfig"]["UseFreq"]) + Params.ENDSWITH_TXT))
|
||||
result = PublicFunc.examine_file(Config["Path"]["Input_BCG"], Filename.BCG_FILTER, Params.ENDSWITH_TXT)
|
||||
if result.status:
|
||||
Config["Path"]["Input_BCG"] = result.data["path"]
|
||||
@ -1716,11 +1875,11 @@ class Data:
|
||||
Filename.RPEAK_FINAL_CORRECTED + ":" +
|
||||
Config["Path"]["Input_Rpeak"] +
|
||||
Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
if not Path(Config["Path"]["Input_Approximately_Align"]).exists():
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
|
||||
Filename.APPROXIMATELY_ALIGN_INFO + ":" +
|
||||
Config["Path"]["Input_Approximately_Align"] +
|
||||
Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
# if not Path(Config["Path"]["Input_Approximately_Align"]).exists():
|
||||
# return Result().failure(info=Constants.INPUT_FAILURE + "\n" +
|
||||
# Filename.APPROXIMATELY_ALIGN_INFO + ":" +
|
||||
# Config["Path"]["Input_Approximately_Align"] +
|
||||
# Constants.FAILURE_REASON["Path_Not_Exist"])
|
||||
|
||||
try:
|
||||
self.raw_orgBcg = read_csv(Config["Path"]["Input_OrgBCG"],
|
||||
@ -1760,9 +1919,21 @@ class Data:
|
||||
self.approximately_align_slope = df["estimate_slope"].values[-1] / \
|
||||
Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Second_PerEpoch"]
|
||||
self.approximately_align_intercept = df["estimate_intercept"].values[-1] * Config["InputConfig"]["UseFreq"]
|
||||
self.TimeBiasSecond = self.approximately_align_pos
|
||||
|
||||
except Exception:
|
||||
self.approximately_align_pos = 0
|
||||
self.approximately_align_pos = abs(self.TimeBiasSecond)
|
||||
if self.approximately_align_pos > 0:
|
||||
if self.TimeBiasSecond > 0:
|
||||
self.BCG_early = True
|
||||
else:
|
||||
self.BCG_early = False
|
||||
else:
|
||||
self.BCG_early = None
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return Result().success(info=Constants.INPUT_FINISHED)
|
||||
|
||||
@ -1970,8 +2141,8 @@ class Data:
|
||||
Config["back"]["anchor_J"] = Config["back"]["anchor_J"] + Config["offset_anchor"]
|
||||
Config["frontcut_index_BCG"] -= Config["offset_anchor"]
|
||||
|
||||
self.res_BCG = ss_resample(self.res_BCG, Config["orgfs"], Config["InputConfig"]["UseFreq"])
|
||||
self.res_orgBcg = ss_resample(self.res_orgBcg, Config["orgfs"], Config["InputConfig"]["UseFreq"])
|
||||
self.res_BCG = rspy_resample(self.res_BCG, Config["orgfs"], Config["InputConfig"]["UseFreq"])
|
||||
self.res_orgBcg = rspy_resample(self.res_orgBcg, Config["orgfs"], Config["InputConfig"]["UseFreq"])
|
||||
|
||||
Config["front"]["anchor_J"] = round(int(Config["front"]["anchor_J"]) * Config["InputConfig"]["UseFreq"] / Config["orgfs"])
|
||||
Config["back"]["anchor_J"] = round(int(Config["back"]["anchor_J"]) * Config["InputConfig"]["UseFreq"] / Config["orgfs"])
|
||||
@ -1992,6 +2163,7 @@ class Data:
|
||||
Config["frontcut_index_BCG"] -= Config["offset_anchor"] * Config["orgfs"] / Config["InputConfig"]["UseFreq"]
|
||||
|
||||
datalen = np_min([len(self.cut_ECG), len(self.res_BCG)])
|
||||
print(f"datalen: {datalen} len cut_ECG: {len(self.cut_ECG)} len res_BCG: {len(self.res_BCG)}")
|
||||
self.cut_ECG = self.cut_ECG[:datalen]
|
||||
self.res_BCG = self.res_BCG[:datalen]
|
||||
self.res_orgBcg = self.res_orgBcg[:datalen]
|
||||
@ -2120,7 +2292,7 @@ class Data:
|
||||
"back_ECG": Config["backcut_index_ECG"]
|
||||
}
|
||||
}
|
||||
save_data = [str(save_data)]
|
||||
save_data = [str(PublicFunc.sanitize_data(save_data))]
|
||||
DataFrame(save_data).to_csv(Config["Path"]["Save_AlignInfo"], index=False, header=False)
|
||||
except PermissionError as e:
|
||||
return Result().failure(info=Constants.SAVE_FAILURE + Constants.FAILURE_REASON["Save_Permission_Denied"])
|
||||
@ -2135,10 +2307,10 @@ class Data:
|
||||
not Path(Config["Path"]["Save_OrgBCG"]).parent.is_dir()):
|
||||
Path(Config["Path"]["Save_OrgBCG"]).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if Config["InputConfig"]["orgBcgFreq"] != Config["InputConfig"]["UseFreq"]:
|
||||
self.res_orgBcg = ss_resample(self.res_orgBcg,
|
||||
int(len(self.res_orgBcg) *
|
||||
(Config["InputConfig"]["orgBcgFreq"] / Config["InputConfig"]["UseFreq"])))
|
||||
# if Config["InputConfig"]["orgBcgFreq"] != Config["InputConfig"]["UseFreq"]:
|
||||
# self.res_orgBcg = ss_resample(self.res_orgBcg,
|
||||
# int(len(self.res_orgBcg) *
|
||||
# (Config["InputConfig"]["orgBcgFreq"] / Config["InputConfig"]["UseFreq"])))
|
||||
|
||||
if self.res_orgBcg is None:
|
||||
return Result().failure(info=Constants.PRECISELY_ALIGN_SAVING_RES_ORGBCG_FAILURE +
|
||||
|
||||
@ -199,6 +199,11 @@ class Params:
|
||||
LABEL_CHECK_LABEL_TRANSPARENCY: float = 0.2
|
||||
LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY: str = "Z"
|
||||
|
||||
LABEL_CHECK_BTN_PREV_MOVE_SHORTCUT_KEY = "A"
|
||||
LABEL_CHECK_BTN_NEXT_MOVE_SHORTCUT_KEY = "D"
|
||||
LABEL_CHECK_BTN_PAUSE_SHORTCUT_KEY = "S"
|
||||
LABEL_CHECK_BTN_UPDATE_STATE_SHORTCUT_KEY = "Space"
|
||||
|
||||
# 数据精同步
|
||||
PRECISELY_ALIGN_CONFIG_FILE_PATH: str = "./config/Config_precisely_align.yaml"
|
||||
PRECISELY_ALIGN_CONFIG_NEW_CONTENT: dict = {
|
||||
@ -215,30 +220,39 @@ class Params:
|
||||
PRECISELY_ALIGN_LABEL_TRANSPARENCY: float = 0.2
|
||||
|
||||
# 冗余数据切割和标签映射
|
||||
CUT_PSG_CONFIG_FILE_PATH: str = "./config/Config_cut_PSG.yaml"
|
||||
CUT_PSG_CONFIG_NEW_CONTENT: dict = {
|
||||
CUT_PAIR_FILE_CONFIG_FILE_PATH: str = "./config/Config_cut_PAIR_FILE.yaml"
|
||||
CUT_PAIR_FILE_CONFIG_NEW_CONTENT: dict = {
|
||||
"ECGFreq": 1000,
|
||||
"BCGFreq": 1000,
|
||||
"ChannelInput": {
|
||||
"Effort Tho": Filename.THO_RAW,
|
||||
"Effort Abd": Filename.ABD_RAW,
|
||||
"Flow T": Filename.FLOWT_RAW,
|
||||
"Flow P": Filename.FLOWP_RAW,
|
||||
"Snore": Filename.SNORE_RAW,
|
||||
"SpO2": Filename.SPO2_RAW,
|
||||
"5_class": Filename.FIVE_CLASS_RAW
|
||||
"Effort Tho": "PSG:" + Filename.THO_RAW,
|
||||
"Effort Abd": "PSG:" + Filename.ABD_RAW,
|
||||
"Flow T": "PSG:" + Filename.FLOWT_RAW,
|
||||
"Flow P": "PSG:" + Filename.FLOWP_RAW,
|
||||
"Snore": "PSG:" + Filename.SNORE_RAW,
|
||||
"SpO2": "PSG:" + Filename.SPO2_RAW,
|
||||
"5_class": "PSG:" + Filename.FIVE_CLASS_RAW
|
||||
},
|
||||
"OrgBCGChannelInput":{
|
||||
"OrgBCG": "OrgBCG:OrgBCG_Raw_"
|
||||
},
|
||||
"ECGChannelInput": {
|
||||
"ECG": "PSG:" + Filename.ECG_RAW
|
||||
},
|
||||
"LabelInput": {
|
||||
"SA Label": Filename.SA_LABEL_RAW
|
||||
},
|
||||
"StartTime": Filename.STARTTIME_RAW,
|
||||
"ChannelSave": {
|
||||
"Effort Tho": Filename.THO_SYNC,
|
||||
"Effort Abd": Filename.ABD_SYNC,
|
||||
"Flow T": Filename.FLOWT_SYNC,
|
||||
"Flow P": Filename.FLOWP_SYNC,
|
||||
"Snore": Filename.SNORE_SYNC,
|
||||
"SpO2": Filename.SPO2_SYNC,
|
||||
"5_class": Filename.FIVE_CLASS_SYNC
|
||||
"Effort Tho": "PSG:" + Filename.THO_SYNC,
|
||||
"Effort Abd": "PSG:" + Filename.ABD_SYNC,
|
||||
"Flow T": "PSG:" + Filename.FLOWT_SYNC,
|
||||
"Flow P": "PSG:" + Filename.FLOWP_SYNC,
|
||||
"Snore": "PSG:" + Filename.SNORE_SYNC,
|
||||
"SpO2": "PSG:" + Filename.SPO2_SYNC,
|
||||
"5_class": "PSG:" + Filename.FIVE_CLASS_SYNC,
|
||||
"OrgBCG": "OrgBCG:" + Filename.ORGBCG_SYNC,
|
||||
"ECG": "PSG:" + Filename.ECG_SYNC
|
||||
},
|
||||
"LabelSave": {
|
||||
"SA Label": Filename.SA_LABEL_SYNC
|
||||
@ -253,10 +267,12 @@ class Params:
|
||||
"SpO2": ENDSWITH_TXT,
|
||||
"5_class": ENDSWITH_TXT,
|
||||
"SA Label": ENDSWITH_CSV,
|
||||
"StartTime": ENDSWITH_TXT
|
||||
"StartTime": ENDSWITH_TXT,
|
||||
"OrgBCG": ENDSWITH_TXT,
|
||||
"ECG": ENDSWITH_TXT
|
||||
},
|
||||
}
|
||||
CUT_PSG_SALABEL_EVENT: list = ["Hypopnea", "Central apnea", "Obstructive apnea", "Mixed apnea"]
|
||||
CUT_PAIR_FILE_SALABEL_EVENT: list = ["Hypopnea", "Central apnea", "Obstructive apnea", "Mixed apnea"]
|
||||
|
||||
# 体动标注
|
||||
ARTIFACT_LABEL_CONFIG_FILE_PATH: str = "./config/Config_artifact_label.yaml"
|
||||
|
||||
@ -5,6 +5,7 @@ class Constants:
|
||||
|
||||
# 公共
|
||||
TIPS_TYPE_INFO: str = "Info"
|
||||
TIPS_TYPE_WARNING: str = "Warning"
|
||||
TIPS_TYPE_ERROR: str = "Error"
|
||||
MSGBOX_TYPE_INFO: str = "Info"
|
||||
MSGBOX_TYPE_WARNING: str = "Warning"
|
||||
@ -182,7 +183,11 @@ 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": "(计算粗对齐信息异常)",
|
||||
"Delete_Rough_Cut_File_Exception": "(删除历史粗对齐文件异常)",
|
||||
"Resample_BCG_Exception": "(粗对齐重采样BCG异常)",
|
||||
}
|
||||
|
||||
# 数据粗同步
|
||||
@ -352,17 +357,31 @@ class Constants:
|
||||
PRECISELY_ALIGN_ACTION_GET_RANGE_NAME: str = f"设置范围({Params.PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY})"
|
||||
|
||||
# 冗余数据切割和标签映射
|
||||
CUT_PSG_GETTING_FILE_AND_FREQ: str = "正在获取文件及其采样率"
|
||||
CUT_PSG_GET_FILE_AND_FREQ_FINISHED: str = "获取文件及其采样率完成"
|
||||
CUT_PSG_GET_FILE_AND_FREQ_FAILURE: str = "获取文件及其采样率失败"
|
||||
CUT_PAIR_FILE_GETTING_FILE_AND_FREQ: str = "正在获取文件及其采样率"
|
||||
CUT_PAIR_FILE_GET_FILE_AND_FREQ_FINISHED: str = "获取文件及其采样率完成"
|
||||
CUT_PAIR_FILE_GET_FILE_AND_FREQ_FAILURE: str = "获取文件及其采样率失败"
|
||||
|
||||
CUT_PSG_CUTTING_DATA: str = "正在切割数据"
|
||||
CUT_PSG_CUT_DATA_FINISHED: str = "切割数据完成"
|
||||
CUT_PSG_CUT_DATA_FAILURE: str = "切割数据失败"
|
||||
CUT_PAIR_FILE_CUTTING_DATA: str = "正在切割数据"
|
||||
CUT_PAIR_FILE_CUT_DATA_FINISHED: str = "切割数据完成"
|
||||
CUT_PAIR_FILE_CUT_DATA_FAILURE: str = "切割数据失败"
|
||||
|
||||
CUT_PAIR_FILE_ALIGNING_LABEL: str = "正在映射标签"
|
||||
CUT_PAIR_FILE_ALIGN_LABEL_FINISHED: str = "映射标签完成"
|
||||
CUT_PAIR_FILE_ALIGN_LABEL_FAILURE: str = "映射标签失败"
|
||||
|
||||
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 = "计算粗对齐信息完成"
|
||||
|
||||
CUT_PAIR_FILE_DELETING_ROUGH_CUT_FILE: str = "正在删除历史粗对齐文件"
|
||||
CUT_PAIR_FILE_DELETE_ROUGH_CUT_FILE_FINISHED: str = "删除历史粗对齐文件完成"
|
||||
CUT_PAIR_FILE_DELETE_ROUGH_CUT_FILE_FAILURE: str = "删除历史粗对齐文件失败"
|
||||
|
||||
CUT_PAIR_FILE_ROUGH_RESAMPLE_BCG: str = "正在粗对齐重采样BCG"
|
||||
CUT_PAIR_FILE_ROUGH_RESAMPLE_BCG_FINISHED: str = "粗对齐重采样BCG完成"
|
||||
CUT_PAIR_FILE_ROUGH_RESAMPLE_BCG_FAILURE: str = "粗对齐重采样BCG失败"
|
||||
|
||||
CUT_PSG_ALIGNING_LABEL: str = "正在映射标签"
|
||||
CUT_PSG_ALIGN_LABEL_FINISHED: str = "映射标签完成"
|
||||
CUT_PSG_ALIGN_LABEL_FAILURE: str = "映射标签失败"
|
||||
|
||||
# 体动标注
|
||||
ARTIFACT_LABEL_PLOT_LABEL_ORGBCG_SYNC: str = "OrgBCG_Sync"
|
||||
|
||||
@ -8,7 +8,7 @@ from PySide6.QtWidgets import QMessageBox, QWidget, QPushButton, QProgressBar, Q
|
||||
from func.utils.Constants import Constants
|
||||
from func.utils.CustomException import TipsTypeValueNotExistError, MsgBoxTypeValueNotExistError
|
||||
from func.utils.Result import Result
|
||||
|
||||
import numpy as np
|
||||
|
||||
class PublicFunc:
|
||||
|
||||
@ -113,6 +113,10 @@ class PublicFunc:
|
||||
if widget.objectName() in buttonState["Current"].keys():
|
||||
widget.setEnabled(False)
|
||||
|
||||
if isinstance(widget, QCheckBox):
|
||||
if widget.objectName() in buttonState["Current"].keys():
|
||||
widget.setEnabled(False)
|
||||
|
||||
@staticmethod
|
||||
def __enableAllButton__(mainWindow, buttonState):
|
||||
# 启用按钮
|
||||
@ -128,6 +132,10 @@ class PublicFunc:
|
||||
if widget.objectName() in buttonState["Current"].keys():
|
||||
widget.setEnabled(buttonState["Current"][widget.objectName()])
|
||||
|
||||
if isinstance(widget, QCheckBox):
|
||||
if widget.objectName() in buttonState["Current"].keys():
|
||||
widget.setEnabled(buttonState["Current"][widget.objectName()])
|
||||
|
||||
@staticmethod
|
||||
def __resetAllButton__(mainWindow, buttonState):
|
||||
# 启用按钮
|
||||
@ -143,6 +151,10 @@ class PublicFunc:
|
||||
if widget.objectName() in buttonState["Default"].keys():
|
||||
widget.setEnabled(buttonState["Default"][widget.objectName()])
|
||||
|
||||
if isinstance(widget, QCheckBox):
|
||||
if widget.objectName() in buttonState["Default"].keys():
|
||||
widget.setEnabled(buttonState["Default"][widget.objectName()])
|
||||
|
||||
@staticmethod
|
||||
def __styleAllButton__(mainWindow, buttonState):
|
||||
# 启用按钮
|
||||
@ -307,4 +319,22 @@ class PublicFunc:
|
||||
for i in range(0, len(artifact), 4):
|
||||
unit_data = artifact[i:i + 4]
|
||||
if len(unit_data) < 4:
|
||||
break
|
||||
break
|
||||
|
||||
@staticmethod
|
||||
def sanitize_data(obj):
|
||||
"""
|
||||
递归将对象中的 NumPy 类型转换为 Python 原生类型
|
||||
"""
|
||||
if isinstance(obj, dict):
|
||||
return {k: PublicFunc._sanitize_data(v) for k, v in obj.items()}
|
||||
elif isinstance(obj, (list, tuple)):
|
||||
return [PublicFunc._sanitize_data(i) for i in obj]
|
||||
elif isinstance(obj, (np.integer, np.int64)):
|
||||
return int(obj)
|
||||
elif isinstance(obj, (np.floating, np.float64)):
|
||||
return float(obj)
|
||||
elif isinstance(obj, np.ndarray):
|
||||
return obj.tolist()
|
||||
else:
|
||||
return obj
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import torch
|
||||
from numpy import diff, argwhere, argmax, where, delete, insert, mean, array, full, nan
|
||||
from numpy import min as np_min
|
||||
from numpy import max as np_max
|
||||
@ -5,11 +6,12 @@ from torch import FloatTensor, no_grad, load
|
||||
from torch import device as torch_device
|
||||
from torch.cuda import is_available, empty_cache
|
||||
from torch.nn.functional import sigmoid
|
||||
from torch.utils.data import TensorDataset, DataLoader
|
||||
|
||||
from func.BCGDataset import BCG_Operation
|
||||
from func.Deep_Model import Unet,Fivelayer_Lstm_Unet,Fivelayer_Unet,Sixlayer_Unet
|
||||
|
||||
def evaluate(test_data, model,fs,useCPU):
|
||||
def evaluate(test_data, model,fs,useCPU, batch_size=0, scale=0):
|
||||
orgBCG = test_data
|
||||
operation = BCG_Operation()
|
||||
# 降采样
|
||||
@ -17,7 +19,12 @@ def evaluate(test_data, model,fs,useCPU):
|
||||
# plt.figure()
|
||||
# plt.plot(orgBCG)
|
||||
# plt.show()
|
||||
if scale != 0:
|
||||
orgBCG_std = orgBCG.std()
|
||||
orgBCG = orgBCG * scale / orgBCG_std
|
||||
|
||||
orgBCG = orgBCG.reshape(-1, 1000)
|
||||
|
||||
# test dataset
|
||||
orgData = FloatTensor(orgBCG).unsqueeze(1)
|
||||
# predict
|
||||
@ -30,12 +37,32 @@ def evaluate(test_data, model,fs,useCPU):
|
||||
# if gpu:
|
||||
# orgData = orgData.cuda()
|
||||
# model.cuda()
|
||||
orgData = orgData.to(device)
|
||||
model = model.to(device)
|
||||
|
||||
model.to(device)
|
||||
orgData_tensor = FloatTensor(orgBCG).unsqueeze(1)
|
||||
test_dataset = TensorDataset(orgData_tensor)
|
||||
batch_size = len(test_dataset) if batch_size == 0 else batch_size
|
||||
#全部数据放在一个batch里评估
|
||||
test_loader = DataLoader(
|
||||
dataset=test_dataset,
|
||||
batch_size=batch_size,
|
||||
shuffle=False,
|
||||
num_workers=0 # 简单评估时设为 0
|
||||
)
|
||||
all_y_prob = []
|
||||
with no_grad():
|
||||
y_hat = model(orgData)
|
||||
y_prob = sigmoid(y_hat)
|
||||
for i, data_batch in enumerate(test_loader):
|
||||
# data_batch 是一个包含 (batch_size, 1, 1000) 数据的列表
|
||||
inputs = data_batch[0].to(device)
|
||||
|
||||
# 预测
|
||||
y_hat_batch = model(inputs)
|
||||
y_prob_batch = sigmoid(y_hat_batch)
|
||||
|
||||
# 收集结果,移回 CPU
|
||||
all_y_prob.append(y_prob_batch.cpu())
|
||||
|
||||
y_prob = torch.cat(all_y_prob, dim=0).view(-1)
|
||||
beat = (y_prob>0.5).float().view(-1).cpu().data.numpy()
|
||||
beat_diff = diff(beat)
|
||||
up_index = argwhere(beat_diff==1)
|
||||
@ -250,7 +277,7 @@ def preprocess(raw_bcg, fs, low_cut, high_cut, amp_value):
|
||||
bcg = preprocessing.Butterworth(bcg_data, "bandpass", low_cut=low_cut, high_cut=high_cut, order=3) * amp_value
|
||||
return bcg
|
||||
|
||||
def Jpeak_Detection(model_name, model_path, bcg_data, fs, interval_high, interval_low, peaks_value, useCPU):
|
||||
def Jpeak_Detection(model_name, model_path, bcg_data, fs, interval_high, interval_low, peaks_value, useCPU, batch_size=0, scale=0):
|
||||
|
||||
model_name = get_model_name(str(model_name))
|
||||
if model_name == "Fivelayer_Unet":
|
||||
@ -267,7 +294,7 @@ def Jpeak_Detection(model_name, model_path, bcg_data, fs, interval_high, interva
|
||||
model.eval()
|
||||
|
||||
# J峰预测
|
||||
beat, up_index, down_index, y_prob = evaluate(bcg_data, model=model, fs=fs, useCPU=useCPU)
|
||||
beat, up_index, down_index, y_prob = evaluate(bcg_data, model=model, fs=fs, useCPU=useCPU, batch_size=batch_size, scale=scale)
|
||||
y_prob = y_prob.cpu().reshape(-1).data.numpy()
|
||||
|
||||
predict_J = new_calculate_beat(y_prob, 1, th=0.6, up=fs // 100, th1=interval_high, th2=interval_low)
|
||||
|
||||
@ -16,10 +16,10 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QAbstractSpinBox, QApplication, QCheckBox, QGridLayout,
|
||||
QGroupBox, QHBoxLayout, QLabel, QMainWindow,
|
||||
QPushButton, QRadioButton, QSizePolicy, QSpacerItem,
|
||||
QSpinBox, QStatusBar, QTextBrowser, QVBoxLayout,
|
||||
QWidget)
|
||||
QGroupBox, QHBoxLayout, QLabel, QLineEdit,
|
||||
QMainWindow, QPushButton, QRadioButton, QSizePolicy,
|
||||
QSpacerItem, QSpinBox, QStatusBar, QTextBrowser,
|
||||
QVBoxLayout, QWidget)
|
||||
|
||||
class Ui_MainWindow_approximately_align(object):
|
||||
def setupUi(self, MainWindow_approximately_align):
|
||||
@ -400,26 +400,43 @@ class Ui_MainWindow_approximately_align(object):
|
||||
self.groupBox_2.setMinimumSize(QSize(0, 0))
|
||||
self.layoutWidget = QWidget(self.groupBox_2)
|
||||
self.layoutWidget.setObjectName(u"layoutWidget")
|
||||
self.layoutWidget.setGeometry(QRect(11, 18, 401, 41))
|
||||
self.layoutWidget.setGeometry(QRect(11, 18, 411, 60))
|
||||
self.verticalLayout_3 = QVBoxLayout(self.layoutWidget)
|
||||
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
||||
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_3 = QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
||||
self.radioButton_freqTHO = QRadioButton(self.layoutWidget)
|
||||
self.radioButton_freqTHO.setObjectName(u"radioButton_freqTHO")
|
||||
self.radioButton_freqTHO.setFont(font1)
|
||||
self.gridLayout_5 = QGridLayout()
|
||||
self.gridLayout_5.setObjectName(u"gridLayout_5")
|
||||
self.radioButton_customFreq = QRadioButton(self.layoutWidget)
|
||||
self.radioButton_customFreq.setObjectName(u"radioButton_customFreq")
|
||||
self.radioButton_customFreq.setFont(font1)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.radioButton_freqTHO)
|
||||
self.gridLayout_5.addWidget(self.radioButton_customFreq, 1, 0, 1, 1)
|
||||
|
||||
self.radioButton_freqABD = QRadioButton(self.layoutWidget)
|
||||
self.radioButton_freqABD.setObjectName(u"radioButton_freqABD")
|
||||
self.radioButton_freqABD.setFont(font1)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.radioButton_freqABD)
|
||||
self.gridLayout_5.addWidget(self.radioButton_freqABD, 0, 1, 1, 1)
|
||||
|
||||
self.radioButton_freqTHO = QRadioButton(self.layoutWidget)
|
||||
self.radioButton_freqTHO.setObjectName(u"radioButton_freqTHO")
|
||||
self.radioButton_freqTHO.setFont(font1)
|
||||
|
||||
self.gridLayout_5.addWidget(self.radioButton_freqTHO, 0, 0, 1, 1)
|
||||
|
||||
self.lineEdit_customFreq = QLineEdit(self.layoutWidget)
|
||||
self.lineEdit_customFreq.setObjectName(u"lineEdit_customFreq")
|
||||
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)
|
||||
sizePolicy1.setHorizontalStretch(0)
|
||||
sizePolicy1.setVerticalStretch(0)
|
||||
sizePolicy1.setHeightForWidth(self.lineEdit_customFreq.sizePolicy().hasHeightForWidth())
|
||||
self.lineEdit_customFreq.setSizePolicy(sizePolicy1)
|
||||
self.lineEdit_customFreq.setFont(font1)
|
||||
|
||||
self.gridLayout_5.addWidget(self.lineEdit_customFreq, 1, 1, 1, 1)
|
||||
|
||||
|
||||
self.verticalLayout_3.addLayout(self.horizontalLayout_3)
|
||||
self.verticalLayout_3.addLayout(self.gridLayout_5)
|
||||
|
||||
|
||||
self.verticalLayout.addWidget(self.groupBox_2)
|
||||
@ -530,7 +547,7 @@ class Ui_MainWindow_approximately_align(object):
|
||||
self.verticalLayout.setStretch(2, 3)
|
||||
self.verticalLayout.setStretch(3, 4)
|
||||
self.verticalLayout.setStretch(4, 3)
|
||||
self.verticalLayout.setStretch(5, 2)
|
||||
self.verticalLayout.setStretch(5, 3)
|
||||
self.verticalLayout.setStretch(6, 4)
|
||||
self.verticalLayout.setStretch(7, 1)
|
||||
self.verticalLayout.setStretch(8, 6)
|
||||
@ -607,8 +624,9 @@ class Ui_MainWindow_approximately_align(object):
|
||||
self.pushButton_GetPos.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u8ba1\u7b97\u5bf9\u9f50", None))
|
||||
self.radioButton_NABD.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90094", None))
|
||||
self.groupBox_2.setTitle(QCoreApplication.translate("MainWindow_approximately_align", u"\u91c7\u6837\u7387\u4f30\u8ba1", None))
|
||||
self.radioButton_freqTHO.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90091", None))
|
||||
self.radioButton_customFreq.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u81ea\u5b9a\u4e49", None))
|
||||
self.radioButton_freqABD.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90092", None))
|
||||
self.radioButton_freqTHO.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u5907\u90091", None))
|
||||
self.groupBox_view_partially.setTitle(QCoreApplication.translate("MainWindow_approximately_align", u"\u5c40\u90e8\u89c2\u6d4b", None))
|
||||
self.label_9.setText(QCoreApplication.translate("MainWindow_approximately_align", u"Epoch\uff1a", None))
|
||||
self.pushButton_JUMP.setText(QCoreApplication.translate("MainWindow_approximately_align", u"\u8df3\u8f6c", None))
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
<property name="title">
|
||||
<string>数据粗同步</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,1,3,4,3,2,4,1,6">
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,1,3,4,3,3,4,1,6">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
@ -728,14 +728,38 @@
|
||||
<rect>
|
||||
<x>11</x>
|
||||
<y>18</y>
|
||||
<width>401</width>
|
||||
<height>41</height>
|
||||
<width>411</width>
|
||||
<height>60</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="1" column="0">
|
||||
<widget class="QRadioButton" name="radioButton_customFreq">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>自定义</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="radioButton_freqABD">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>备选2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="radioButton_freqTHO">
|
||||
<property name="font">
|
||||
<font>
|
||||
@ -747,16 +771,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButton_freqABD">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_customFreq">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>备选2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'MainWindow_cut_PSG.ui'
|
||||
## Form generated from reading UI file 'MainWindow_cut_PAIR_FILE.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.8.2
|
||||
## Created by: Qt User Interface Compiler version 6.9.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
@ -16,35 +16,36 @@ from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
|
||||
QIcon, QImage, QKeySequence, QLinearGradient,
|
||||
QPainter, QPalette, QPixmap, QRadialGradient,
|
||||
QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QGridLayout, QGroupBox, QHBoxLayout,
|
||||
QLabel, QMainWindow, QPlainTextEdit, QProgressBar,
|
||||
QPushButton, QSizePolicy, QSpacerItem, QSpinBox,
|
||||
QStatusBar, QTextBrowser, QVBoxLayout, QWidget)
|
||||
from PySide6.QtWidgets import (QApplication, QCheckBox, QGridLayout, QGroupBox,
|
||||
QHBoxLayout, QLabel, QMainWindow, QPlainTextEdit,
|
||||
QProgressBar, QPushButton, QSizePolicy, QSpacerItem,
|
||||
QSpinBox, QStatusBar, QTextBrowser, QVBoxLayout,
|
||||
QWidget)
|
||||
|
||||
class Ui_MainWindow_cut_PSG(object):
|
||||
def setupUi(self, MainWindow_cut_PSG):
|
||||
if not MainWindow_cut_PSG.objectName():
|
||||
MainWindow_cut_PSG.setObjectName(u"MainWindow_cut_PSG")
|
||||
MainWindow_cut_PSG.setEnabled(True)
|
||||
MainWindow_cut_PSG.resize(540, 720)
|
||||
class Ui_MainWindow_cut_PAIR_FILE(object):
|
||||
def setupUi(self, MainWindow_cut_PAIR_FILE):
|
||||
if not MainWindow_cut_PAIR_FILE.objectName():
|
||||
MainWindow_cut_PAIR_FILE.setObjectName(u"MainWindow_cut_PAIR_FILE")
|
||||
MainWindow_cut_PAIR_FILE.setEnabled(True)
|
||||
MainWindow_cut_PAIR_FILE.resize(548, 739)
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Ignored, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(MainWindow_cut_PSG.sizePolicy().hasHeightForWidth())
|
||||
MainWindow_cut_PSG.setSizePolicy(sizePolicy)
|
||||
sizePolicy.setHeightForWidth(MainWindow_cut_PAIR_FILE.sizePolicy().hasHeightForWidth())
|
||||
MainWindow_cut_PAIR_FILE.setSizePolicy(sizePolicy)
|
||||
font = QFont()
|
||||
font.setPointSize(12)
|
||||
MainWindow_cut_PSG.setFont(font)
|
||||
self.action_selectPath = QAction(MainWindow_cut_PSG)
|
||||
MainWindow_cut_PAIR_FILE.setFont(font)
|
||||
self.action_selectPath = QAction(MainWindow_cut_PAIR_FILE)
|
||||
self.action_selectPath.setObjectName(u"action_selectPath")
|
||||
font1 = QFont()
|
||||
font1.setFamilies([u"\u9ed1\u4f53"])
|
||||
font1.setPointSize(14)
|
||||
self.action_selectPath.setFont(font1)
|
||||
self.action = QAction(MainWindow_cut_PSG)
|
||||
self.action = QAction(MainWindow_cut_PAIR_FILE)
|
||||
self.action.setObjectName(u"action")
|
||||
self.action.setFont(font1)
|
||||
self.centralwidget = QWidget(MainWindow_cut_PSG)
|
||||
self.centralwidget = QWidget(MainWindow_cut_PAIR_FILE)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.gridLayout = QGridLayout(self.centralwidget)
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
@ -55,22 +56,33 @@ class Ui_MainWindow_cut_PSG(object):
|
||||
self.groupBox_3.setFont(font2)
|
||||
self.gridLayout_2 = QGridLayout(self.groupBox_3)
|
||||
self.gridLayout_2.setObjectName(u"gridLayout_2")
|
||||
self.groupBox = QGroupBox(self.groupBox_3)
|
||||
self.groupBox.setObjectName(u"groupBox")
|
||||
self.verticalLayout_6 = QVBoxLayout(self.groupBox)
|
||||
self.verticalLayout_6.setObjectName(u"verticalLayout_6")
|
||||
self.textBrowser_info = QTextBrowser(self.groupBox)
|
||||
self.textBrowser_info.setObjectName(u"textBrowser_info")
|
||||
|
||||
self.verticalLayout_6.addWidget(self.textBrowser_info)
|
||||
|
||||
|
||||
self.gridLayout_2.addWidget(self.groupBox, 1, 0, 1, 1)
|
||||
|
||||
self.groupBox_2 = QGroupBox(self.groupBox_3)
|
||||
self.groupBox_2.setObjectName(u"groupBox_2")
|
||||
self.verticalLayout_5 = QVBoxLayout(self.groupBox_2)
|
||||
self.verticalLayout_5.setObjectName(u"verticalLayout_5")
|
||||
self.horizontalLayout_3 = QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
||||
self.checkBox_roughCut = QCheckBox(self.groupBox_2)
|
||||
self.checkBox_roughCut.setObjectName(u"checkBox_roughCut")
|
||||
self.checkBox_roughCut.setFont(font)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.checkBox_roughCut)
|
||||
|
||||
self.checkBox_roughResample = QCheckBox(self.groupBox_2)
|
||||
self.checkBox_roughResample.setObjectName(u"checkBox_roughResample")
|
||||
self.checkBox_roughResample.setFont(font)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.checkBox_roughResample)
|
||||
|
||||
self.pushButton_deleteRoughCut = QPushButton(self.groupBox_2)
|
||||
self.pushButton_deleteRoughCut.setObjectName(u"pushButton_deleteRoughCut")
|
||||
self.pushButton_deleteRoughCut.setFont(font)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.pushButton_deleteRoughCut)
|
||||
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_3)
|
||||
|
||||
self.horizontalLayout = QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.label_2 = QLabel(self.groupBox_2)
|
||||
@ -110,13 +122,23 @@ class Ui_MainWindow_cut_PSG(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.setEnabled(False)
|
||||
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.setEnabled(False)
|
||||
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")
|
||||
@ -124,12 +146,30 @@ class Ui_MainWindow_cut_PSG(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)
|
||||
|
||||
@ -159,15 +199,28 @@ class Ui_MainWindow_cut_PSG(object):
|
||||
|
||||
self.verticalLayout_5.addWidget(self.progressbar)
|
||||
|
||||
self.verticalLayout_5.setStretch(0, 2)
|
||||
self.verticalLayout_5.setStretch(0, 1)
|
||||
self.verticalLayout_5.setStretch(1, 2)
|
||||
self.verticalLayout_5.setStretch(2, 1)
|
||||
self.verticalLayout_5.setStretch(3, 2)
|
||||
self.verticalLayout_5.setStretch(4, 1)
|
||||
self.verticalLayout_5.setStretch(2, 2)
|
||||
self.verticalLayout_5.setStretch(3, 1)
|
||||
self.verticalLayout_5.setStretch(4, 2)
|
||||
self.verticalLayout_5.setStretch(5, 1)
|
||||
self.verticalLayout_5.setStretch(6, 1)
|
||||
|
||||
self.gridLayout_2.addWidget(self.groupBox_2, 0, 0, 1, 2)
|
||||
|
||||
self.groupBox = QGroupBox(self.groupBox_3)
|
||||
self.groupBox.setObjectName(u"groupBox")
|
||||
self.verticalLayout_6 = QVBoxLayout(self.groupBox)
|
||||
self.verticalLayout_6.setObjectName(u"verticalLayout_6")
|
||||
self.textBrowser_info = QTextBrowser(self.groupBox)
|
||||
self.textBrowser_info.setObjectName(u"textBrowser_info")
|
||||
|
||||
self.verticalLayout_6.addWidget(self.textBrowser_info)
|
||||
|
||||
|
||||
self.gridLayout_2.addWidget(self.groupBox, 1, 0, 1, 1)
|
||||
|
||||
self.pushButton_execute = QPushButton(self.groupBox_3)
|
||||
self.pushButton_execute.setObjectName(u"pushButton_execute")
|
||||
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
|
||||
@ -180,34 +233,37 @@ class Ui_MainWindow_cut_PSG(object):
|
||||
self.gridLayout_2.addWidget(self.pushButton_execute, 1, 1, 1, 1)
|
||||
|
||||
self.gridLayout_2.setRowStretch(0, 7)
|
||||
self.gridLayout_2.setRowStretch(1, 3)
|
||||
self.gridLayout_2.setColumnStretch(0, 4)
|
||||
self.gridLayout_2.setColumnStretch(1, 1)
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox_3, 0, 0, 1, 1)
|
||||
|
||||
self.gridLayout.setColumnStretch(0, 2)
|
||||
MainWindow_cut_PSG.setCentralWidget(self.centralwidget)
|
||||
self.statusbar = QStatusBar(MainWindow_cut_PSG)
|
||||
MainWindow_cut_PAIR_FILE.setCentralWidget(self.centralwidget)
|
||||
self.statusbar = QStatusBar(MainWindow_cut_PAIR_FILE)
|
||||
self.statusbar.setObjectName(u"statusbar")
|
||||
MainWindow_cut_PSG.setStatusBar(self.statusbar)
|
||||
MainWindow_cut_PAIR_FILE.setStatusBar(self.statusbar)
|
||||
|
||||
self.retranslateUi(MainWindow_cut_PSG)
|
||||
self.retranslateUi(MainWindow_cut_PAIR_FILE)
|
||||
|
||||
QMetaObject.connectSlotsByName(MainWindow_cut_PSG)
|
||||
QMetaObject.connectSlotsByName(MainWindow_cut_PAIR_FILE)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, MainWindow_cut_PSG):
|
||||
MainWindow_cut_PSG.setWindowTitle(QCoreApplication.translate("MainWindow_cut_PSG", u"\u5197\u4f59\u6570\u636e\u5207\u5272\u548c\u6807\u7b7e\u6620\u5c04", None))
|
||||
self.action_selectPath.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u6570\u636e\u8def\u5f84\u9009\u62e9", None))
|
||||
self.action.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u52a0\u8f7d\u5b58\u6863", None))
|
||||
self.groupBox_3.setTitle(QCoreApplication.translate("MainWindow_cut_PSG", u"\u5197\u4f59\u6570\u636e\u5207\u5272\u548c\u6807\u7b7e\u6620\u5c04", None))
|
||||
self.groupBox.setTitle(QCoreApplication.translate("MainWindow_cut_PSG", u"\u65e5\u5fd7", None))
|
||||
self.groupBox_2.setTitle(QCoreApplication.translate("MainWindow_cut_PSG", u"\u786e\u5b9a\u6570\u636e", None))
|
||||
self.label_2.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u9700\u8981\u5207\u5272\u7684\u901a\u9053\u540d\uff1a", None))
|
||||
self.label_6.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u9700\u8981\u6620\u5c04\u7684\u6807\u7b7e\uff1a", None))
|
||||
self.label_7.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u6570\u636e\u7cbe\u540c\u6b65\u65f6ECG\u7684\u91c7\u6837\u7387\uff1a", None))
|
||||
self.label_show.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u70b9\u51fb\u6267\u884c\u4ee5\u5f00\u59cb...", None))
|
||||
self.pushButton_execute.setText(QCoreApplication.translate("MainWindow_cut_PSG", u"\u6267\u884c", None))
|
||||
def retranslateUi(self, MainWindow_cut_PAIR_FILE):
|
||||
MainWindow_cut_PAIR_FILE.setWindowTitle(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u5197\u4f59\u6570\u636e\u5207\u5272\u548c\u6807\u7b7e\u6620\u5c04", None))
|
||||
self.action_selectPath.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u6570\u636e\u8def\u5f84\u9009\u62e9", None))
|
||||
self.action.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u52a0\u8f7d\u5b58\u6863", None))
|
||||
self.groupBox_3.setTitle(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u5197\u4f59\u6570\u636e\u5207\u5272\u548c\u6807\u7b7e\u6620\u5c04", None))
|
||||
self.groupBox_2.setTitle(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u786e\u5b9a\u6570\u636e", None))
|
||||
self.checkBox_roughCut.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u7c97\u5bf9\u9f50\u7ed3\u679c\u5207\u5272\u6a21\u5f0f", None))
|
||||
self.checkBox_roughResample.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u7c97\u5bf9\u9f50\u91cd\u91c7\u6837", None))
|
||||
self.pushButton_deleteRoughCut.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))
|
||||
# retranslateUi
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow_cut_PSG</class>
|
||||
<widget class="QMainWindow" name="MainWindow_cut_PSG">
|
||||
<class>MainWindow_cut_PAIR_FILE</class>
|
||||
<widget class="QMainWindow" name="MainWindow_cut_PAIR_FILE">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -9,8 +9,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>540</width>
|
||||
<height>720</height>
|
||||
<width>548</width>
|
||||
<height>739</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -39,25 +39,53 @@
|
||||
<property name="title">
|
||||
<string>冗余数据切割和标签映射</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2" rowstretch="7,3" columnstretch="4,1">
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>日志</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="textBrowser_info"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<layout class="QGridLayout" name="gridLayout_2" rowstretch="7,0" columnstretch="4,0">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>确定数据</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="2,2,1,2,1,1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="1,2,2,1,2,1,1">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_roughCut">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>粗对齐结果切割模式</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_roughResample">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>粗对齐重采样</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_deleteRoughCut">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>删除粗对齐切割文件</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1">
|
||||
<item>
|
||||
@ -108,20 +136,41 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7" stretch="1,1">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>数据精同步时ECG的采样率:</string>
|
||||
<string>BCG原始采样率:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<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="1">
|
||||
<widget class="QSpinBox" name="spinBox_ECGFreq">
|
||||
<property name="font">
|
||||
<font>
|
||||
@ -136,6 +185,45 @@
|
||||
</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>
|
||||
@ -189,6 +277,18 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>日志</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="textBrowser_info"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="pushButton_execute">
|
||||
<property name="sizePolicy">
|
||||
@ -3,7 +3,7 @@
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'MainWindow_detect_Jpeak.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.8.2
|
||||
## Created by: Qt User Interface Compiler version 6.9.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
@ -16,10 +16,10 @@ from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
|
||||
QIcon, QImage, QKeySequence, QLinearGradient,
|
||||
QPainter, QPalette, QPixmap, QRadialGradient,
|
||||
QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QDoubleSpinBox,
|
||||
QGridLayout, QGroupBox, QHBoxLayout, QLabel,
|
||||
QMainWindow, QPushButton, QRadioButton, QSizePolicy,
|
||||
QSpacerItem, QSpinBox, QStatusBar, QTextBrowser,
|
||||
from PySide6.QtWidgets import (QAbstractSpinBox, QApplication, QCheckBox, QComboBox,
|
||||
QDoubleSpinBox, QGridLayout, QGroupBox, QHBoxLayout,
|
||||
QLabel, QMainWindow, QPushButton, QRadioButton,
|
||||
QSizePolicy, QSpinBox, QStatusBar, QTextBrowser,
|
||||
QVBoxLayout, QWidget)
|
||||
|
||||
class Ui_MainWindow_detect_Jpeak(object):
|
||||
@ -221,26 +221,77 @@ class Ui_MainWindow_detect_Jpeak(object):
|
||||
|
||||
self.groupBox_3 = QGroupBox(self.groupBox_args)
|
||||
self.groupBox_3.setObjectName(u"groupBox_3")
|
||||
self.verticalLayout_2 = QVBoxLayout(self.groupBox_3)
|
||||
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
||||
self.gridLayout_3 = QGridLayout(self.groupBox_3)
|
||||
self.gridLayout_3.setObjectName(u"gridLayout_3")
|
||||
self.spinBox_scaleValue = QSpinBox(self.groupBox_3)
|
||||
self.spinBox_scaleValue.setObjectName(u"spinBox_scaleValue")
|
||||
self.spinBox_scaleValue.setFont(font)
|
||||
self.spinBox_scaleValue.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_scaleValue.setMinimum(10)
|
||||
self.spinBox_scaleValue.setMaximum(1000)
|
||||
self.spinBox_scaleValue.setValue(100)
|
||||
|
||||
self.gridLayout_3.addWidget(self.spinBox_scaleValue, 1, 1, 1, 1)
|
||||
|
||||
self.checkBox_useCPU = QCheckBox(self.groupBox_3)
|
||||
self.checkBox_useCPU.setObjectName(u"checkBox_useCPU")
|
||||
self.checkBox_useCPU.setFont(font)
|
||||
|
||||
self.verticalLayout_2.addWidget(self.checkBox_useCPU)
|
||||
|
||||
self.label_7 = QLabel(self.groupBox_3)
|
||||
self.label_7.setObjectName(u"label_7")
|
||||
self.label_7.setFont(font)
|
||||
self.label_7.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.verticalLayout_2.addWidget(self.label_7)
|
||||
self.gridLayout_3.addWidget(self.checkBox_useCPU, 0, 0, 1, 1)
|
||||
|
||||
self.comboBox_model = QComboBox(self.groupBox_3)
|
||||
self.comboBox_model.setObjectName(u"comboBox_model")
|
||||
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
||||
sizePolicy2.setHorizontalStretch(0)
|
||||
sizePolicy2.setVerticalStretch(0)
|
||||
sizePolicy2.setHeightForWidth(self.comboBox_model.sizePolicy().hasHeightForWidth())
|
||||
self.comboBox_model.setSizePolicy(sizePolicy2)
|
||||
self.comboBox_model.setFont(font)
|
||||
|
||||
self.verticalLayout_2.addWidget(self.comboBox_model)
|
||||
self.gridLayout_3.addWidget(self.comboBox_model, 4, 1, 1, 1)
|
||||
|
||||
self.checkBox_scaleEnable = QCheckBox(self.groupBox_3)
|
||||
self.checkBox_scaleEnable.setObjectName(u"checkBox_scaleEnable")
|
||||
self.checkBox_scaleEnable.setFont(font)
|
||||
|
||||
self.gridLayout_3.addWidget(self.checkBox_scaleEnable, 1, 0, 1, 1)
|
||||
|
||||
self.label_8 = QLabel(self.groupBox_3)
|
||||
self.label_8.setObjectName(u"label_8")
|
||||
sizePolicy3 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy3.setHorizontalStretch(0)
|
||||
sizePolicy3.setVerticalStretch(0)
|
||||
sizePolicy3.setHeightForWidth(self.label_8.sizePolicy().hasHeightForWidth())
|
||||
self.label_8.setSizePolicy(sizePolicy3)
|
||||
self.label_8.setFont(font)
|
||||
self.label_8.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.gridLayout_3.addWidget(self.label_8, 2, 0, 1, 1)
|
||||
|
||||
self.comboBox_batchSize = QComboBox(self.groupBox_3)
|
||||
self.comboBox_batchSize.addItem("")
|
||||
self.comboBox_batchSize.addItem("")
|
||||
self.comboBox_batchSize.addItem("")
|
||||
self.comboBox_batchSize.addItem("")
|
||||
self.comboBox_batchSize.addItem("")
|
||||
self.comboBox_batchSize.addItem("")
|
||||
self.comboBox_batchSize.addItem("")
|
||||
self.comboBox_batchSize.setObjectName(u"comboBox_batchSize")
|
||||
self.comboBox_batchSize.setFont(font)
|
||||
|
||||
self.gridLayout_3.addWidget(self.comboBox_batchSize, 2, 1, 1, 1)
|
||||
|
||||
self.label_7 = QLabel(self.groupBox_3)
|
||||
self.label_7.setObjectName(u"label_7")
|
||||
sizePolicy4 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy4.setHorizontalStretch(0)
|
||||
sizePolicy4.setVerticalStretch(0)
|
||||
sizePolicy4.setHeightForWidth(self.label_7.sizePolicy().hasHeightForWidth())
|
||||
self.label_7.setSizePolicy(sizePolicy4)
|
||||
self.label_7.setFont(font)
|
||||
self.label_7.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.gridLayout_3.addWidget(self.label_7, 4, 0, 1, 1)
|
||||
|
||||
|
||||
self.verticalLayout_5.addWidget(self.groupBox_3)
|
||||
@ -253,10 +304,6 @@ class Ui_MainWindow_detect_Jpeak(object):
|
||||
|
||||
self.verticalLayout.addWidget(self.groupBox_args)
|
||||
|
||||
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
|
||||
|
||||
self.verticalLayout.addItem(self.verticalSpacer)
|
||||
|
||||
self.horizontalLayout_3 = QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
||||
self.pushButton_view = QPushButton(self.groupBox_left)
|
||||
@ -292,9 +339,8 @@ class Ui_MainWindow_detect_Jpeak(object):
|
||||
|
||||
self.verticalLayout.setStretch(0, 1)
|
||||
self.verticalLayout.setStretch(1, 7)
|
||||
self.verticalLayout.setStretch(2, 4)
|
||||
self.verticalLayout.setStretch(3, 1)
|
||||
self.verticalLayout.setStretch(4, 5)
|
||||
self.verticalLayout.setStretch(2, 1)
|
||||
self.verticalLayout.setStretch(3, 5)
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox_left, 0, 0, 1, 1)
|
||||
|
||||
@ -330,7 +376,17 @@ class Ui_MainWindow_detect_Jpeak(object):
|
||||
self.label_4.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"~", None))
|
||||
self.groupBox_3.setTitle(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u6a21\u578b\u8bbe\u7f6e", None))
|
||||
self.checkBox_useCPU.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u5f3a\u5236\u4f7f\u7528CPU", None))
|
||||
self.label_7.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u68c0\u6d4b\u6a21\u578b\u9009\u62e9", None))
|
||||
self.checkBox_scaleEnable.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u5b9a\u4f4d\u65f6\u5e45\u503c\u653e\u7f29", None))
|
||||
self.label_8.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"Batch Size:", None))
|
||||
self.comboBox_batchSize.setItemText(0, QCoreApplication.translate("MainWindow_detect_Jpeak", u"0", None))
|
||||
self.comboBox_batchSize.setItemText(1, QCoreApplication.translate("MainWindow_detect_Jpeak", u"64", None))
|
||||
self.comboBox_batchSize.setItemText(2, QCoreApplication.translate("MainWindow_detect_Jpeak", u"128", None))
|
||||
self.comboBox_batchSize.setItemText(3, QCoreApplication.translate("MainWindow_detect_Jpeak", u"256", None))
|
||||
self.comboBox_batchSize.setItemText(4, QCoreApplication.translate("MainWindow_detect_Jpeak", u"512", None))
|
||||
self.comboBox_batchSize.setItemText(5, QCoreApplication.translate("MainWindow_detect_Jpeak", u"1024", None))
|
||||
self.comboBox_batchSize.setItemText(6, QCoreApplication.translate("MainWindow_detect_Jpeak", u"2048", None))
|
||||
|
||||
self.label_7.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u68c0\u6d4b\u6a21\u578b\u9009\u62e9\uff1a", None))
|
||||
self.pushButton_view.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u67e5\u770b\u7ed3\u679c", None))
|
||||
self.pushButton_save.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u4fdd\u5b58\u7ed3\u679c", None))
|
||||
self.groupBox.setTitle(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u65e5\u5fd7", None))
|
||||
|
||||
@ -56,7 +56,7 @@
|
||||
<property name="title">
|
||||
<string>BCG的J峰算法定位</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,7,4,1,5">
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,7,1,5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
@ -321,8 +321,29 @@
|
||||
<property name="title">
|
||||
<string>模型设置</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_scaleValue">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_useCPU">
|
||||
<property name="font">
|
||||
<font>
|
||||
@ -334,28 +355,117 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="comboBox_model">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_scaleEnable">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>检测模型选择</string>
|
||||
<string>定位时幅值放缩</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Batch Size:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_model">
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBox_batchSize">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>64</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>128</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>256</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>512</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1024</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2048</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>检测模型选择:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -364,19 +474,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'MainWindow_label_check.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.8.2
|
||||
## Created by: Qt User Interface Compiler version 6.9.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
@ -156,6 +156,14 @@ class Ui_MainWindow_label_check(object):
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.pushButton_pause)
|
||||
|
||||
self.pushButton_update_state = QPushButton(self.groupBox_2)
|
||||
self.pushButton_update_state.setObjectName(u"pushButton_update_state")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_update_state.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_update_state.setSizePolicy(sizePolicy)
|
||||
self.pushButton_update_state.setFont(font1)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.pushButton_update_state)
|
||||
|
||||
self.pushButton_next_move = QPushButton(self.groupBox_2)
|
||||
self.pushButton_next_move.setObjectName(u"pushButton_next_move")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_next_move.sizePolicy().hasHeightForWidth())
|
||||
@ -505,6 +513,13 @@ class Ui_MainWindow_label_check(object):
|
||||
self.groupBox_2.setTitle(QCoreApplication.translate("MainWindow_label_check", u"\u81ea\u52a8\u64ad\u653e", None))
|
||||
self.pushButton_prev_move.setText(QCoreApplication.translate("MainWindow_label_check", u"< <(A)", None))
|
||||
self.pushButton_pause.setText(QCoreApplication.translate("MainWindow_label_check", u"| |(S)", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.pushButton_update_state.setToolTip(QCoreApplication.translate("MainWindow_label_check", u"\u6309\u4e0b\u540e\u6062\u590d\u4e0a\u6b21\u72b6\u6001", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
#if QT_CONFIG(whatsthis)
|
||||
self.pushButton_update_state.setWhatsThis("")
|
||||
#endif // QT_CONFIG(whatsthis)
|
||||
self.pushButton_update_state.setText(QCoreApplication.translate("MainWindow_label_check", u"\u26aa( )", None))
|
||||
self.pushButton_next_move.setText(QCoreApplication.translate("MainWindow_label_check", u"> >(D)", None))
|
||||
self.groupBox_3.setTitle(QCoreApplication.translate("MainWindow_label_check", u"\u8bbe\u7f6e", None))
|
||||
self.label_moveLength_preset_1.setText(QCoreApplication.translate("MainWindow_label_check", u"10000", None))
|
||||
|
||||
@ -237,6 +237,30 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_update_state">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>按下后恢复上次状态</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>⚪( )</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_next_move">
|
||||
<property name="sizePolicy">
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'MainWindow_precisely_align.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.7.0
|
||||
## Created by: Qt User Interface Compiler version 6.9.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
@ -27,7 +27,7 @@ class Ui_MainWindow_precisely_align(object):
|
||||
if not MainWindow_precisely_align.objectName():
|
||||
MainWindow_precisely_align.setObjectName(u"MainWindow_precisely_align")
|
||||
MainWindow_precisely_align.setEnabled(True)
|
||||
MainWindow_precisely_align.resize(1920, 1080)
|
||||
MainWindow_precisely_align.resize(1912, 1061)
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Ignored, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
@ -69,6 +69,37 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.groupBox_left.setFont(font2)
|
||||
self.verticalLayout = QVBoxLayout(self.groupBox_left)
|
||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
||||
self.horizontalLayout_7 = QHBoxLayout()
|
||||
self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
|
||||
self.label_18 = QLabel(self.groupBox_left)
|
||||
self.label_18.setObjectName(u"label_18")
|
||||
self.label_18.setFont(font)
|
||||
self.label_18.setAlignment(Qt.AlignmentFlag.AlignRight|Qt.AlignmentFlag.AlignTrailing|Qt.AlignmentFlag.AlignVCenter)
|
||||
|
||||
self.horizontalLayout_7.addWidget(self.label_18)
|
||||
|
||||
self.label_sampno = QLabel(self.groupBox_left)
|
||||
self.label_sampno.setObjectName(u"label_sampno")
|
||||
self.label_sampno.setFont(font)
|
||||
|
||||
self.horizontalLayout_7.addWidget(self.label_sampno)
|
||||
|
||||
self.label_20 = QLabel(self.groupBox_left)
|
||||
self.label_20.setObjectName(u"label_20")
|
||||
self.label_20.setFont(font)
|
||||
self.label_20.setAlignment(Qt.AlignmentFlag.AlignRight|Qt.AlignmentFlag.AlignTrailing|Qt.AlignmentFlag.AlignVCenter)
|
||||
|
||||
self.horizontalLayout_7.addWidget(self.label_20)
|
||||
|
||||
self.label_pos = QLabel(self.groupBox_left)
|
||||
self.label_pos.setObjectName(u"label_pos")
|
||||
self.label_pos.setFont(font)
|
||||
|
||||
self.horizontalLayout_7.addWidget(self.label_pos)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_7)
|
||||
|
||||
self.horizontalLayout_4 = QHBoxLayout()
|
||||
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
|
||||
self.pushButton_input_setting = QPushButton(self.groupBox_left)
|
||||
@ -138,7 +169,12 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.spinBox_BCG_front_Signal_2 = QSpinBox(self.groupBox_2)
|
||||
self.spinBox_BCG_front_Signal_2.setObjectName(u"spinBox_BCG_front_Signal_2")
|
||||
self.spinBox_BCG_front_Signal_2.setEnabled(False)
|
||||
self.spinBox_BCG_front_Signal_2.setFont(font)
|
||||
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy2.setHorizontalStretch(0)
|
||||
sizePolicy2.setVerticalStretch(0)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_BCG_front_Signal_2.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_BCG_front_Signal_2.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_BCG_front_Signal_2.setFont(font2)
|
||||
self.spinBox_BCG_front_Signal_2.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_BCG_front_Signal_2.setMinimum(0)
|
||||
self.spinBox_BCG_front_Signal_2.setMaximum(1000000000)
|
||||
@ -147,7 +183,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.spinBox_BCG_front_JJIV_1 = QSpinBox(self.groupBox_2)
|
||||
self.spinBox_BCG_front_JJIV_1.setObjectName(u"spinBox_BCG_front_JJIV_1")
|
||||
self.spinBox_BCG_front_JJIV_1.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_BCG_front_JJIV_1.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_BCG_front_JJIV_1.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_BCG_front_JJIV_1.setFont(font2)
|
||||
self.spinBox_BCG_front_JJIV_1.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_BCG_front_JJIV_1.setMinimum(0)
|
||||
self.spinBox_BCG_front_JJIV_1.setMaximum(1000000000)
|
||||
@ -163,7 +201,12 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.label_4 = QLabel(self.groupBox_2)
|
||||
self.label_4.setObjectName(u"label_4")
|
||||
self.label_4.setFont(font)
|
||||
sizePolicy3 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy3.setHorizontalStretch(0)
|
||||
sizePolicy3.setVerticalStretch(0)
|
||||
sizePolicy3.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth())
|
||||
self.label_4.setSizePolicy(sizePolicy3)
|
||||
self.label_4.setFont(font2)
|
||||
self.label_4.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.gridLayout_2.addWidget(self.label_4, 0, 3, 1, 1)
|
||||
@ -171,7 +214,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.spinBox_BCG_front_Signal_1 = QSpinBox(self.groupBox_2)
|
||||
self.spinBox_BCG_front_Signal_1.setObjectName(u"spinBox_BCG_front_Signal_1")
|
||||
self.spinBox_BCG_front_Signal_1.setEnabled(False)
|
||||
self.spinBox_BCG_front_Signal_1.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_BCG_front_Signal_1.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_BCG_front_Signal_1.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_BCG_front_Signal_1.setFont(font2)
|
||||
self.spinBox_BCG_front_Signal_1.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_BCG_front_Signal_1.setMinimum(0)
|
||||
self.spinBox_BCG_front_Signal_1.setMaximum(1000000000)
|
||||
@ -180,7 +225,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.spinBox_BCG_front_JJIV_2 = QSpinBox(self.groupBox_2)
|
||||
self.spinBox_BCG_front_JJIV_2.setObjectName(u"spinBox_BCG_front_JJIV_2")
|
||||
self.spinBox_BCG_front_JJIV_2.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_BCG_front_JJIV_2.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_BCG_front_JJIV_2.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_BCG_front_JJIV_2.setFont(font2)
|
||||
self.spinBox_BCG_front_JJIV_2.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_BCG_front_JJIV_2.setMinimum(0)
|
||||
self.spinBox_BCG_front_JJIV_2.setMaximum(1000000000)
|
||||
@ -189,20 +236,26 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.label_6 = QLabel(self.groupBox_2)
|
||||
self.label_6.setObjectName(u"label_6")
|
||||
self.label_6.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_6.sizePolicy().hasHeightForWidth())
|
||||
self.label_6.setSizePolicy(sizePolicy3)
|
||||
self.label_6.setFont(font2)
|
||||
self.label_6.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.gridLayout_2.addWidget(self.label_6, 1, 3, 1, 1)
|
||||
|
||||
self.label = QLabel(self.groupBox_2)
|
||||
self.label.setObjectName(u"label")
|
||||
self.label.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
|
||||
self.label.setSizePolicy(sizePolicy3)
|
||||
self.label.setFont(font2)
|
||||
|
||||
self.gridLayout_2.addWidget(self.label, 0, 1, 1, 1)
|
||||
|
||||
self.label_2 = QLabel(self.groupBox_2)
|
||||
self.label_2.setObjectName(u"label_2")
|
||||
self.label_2.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
|
||||
self.label_2.setSizePolicy(sizePolicy3)
|
||||
self.label_2.setFont(font2)
|
||||
|
||||
self.gridLayout_2.addWidget(self.label_2, 1, 1, 1, 1)
|
||||
|
||||
@ -221,7 +274,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.spinBox_BCG_back_Signal_2 = QSpinBox(self.groupBox_4)
|
||||
self.spinBox_BCG_back_Signal_2.setObjectName(u"spinBox_BCG_back_Signal_2")
|
||||
self.spinBox_BCG_back_Signal_2.setEnabled(False)
|
||||
self.spinBox_BCG_back_Signal_2.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_BCG_back_Signal_2.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_BCG_back_Signal_2.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_BCG_back_Signal_2.setFont(font2)
|
||||
self.spinBox_BCG_back_Signal_2.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_BCG_back_Signal_2.setMinimum(0)
|
||||
self.spinBox_BCG_back_Signal_2.setMaximum(1000000000)
|
||||
@ -231,7 +286,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.spinBox_BCG_back_Signal_1 = QSpinBox(self.groupBox_4)
|
||||
self.spinBox_BCG_back_Signal_1.setObjectName(u"spinBox_BCG_back_Signal_1")
|
||||
self.spinBox_BCG_back_Signal_1.setEnabled(False)
|
||||
self.spinBox_BCG_back_Signal_1.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_BCG_back_Signal_1.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_BCG_back_Signal_1.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_BCG_back_Signal_1.setFont(font2)
|
||||
self.spinBox_BCG_back_Signal_1.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_BCG_back_Signal_1.setMinimum(0)
|
||||
self.spinBox_BCG_back_Signal_1.setMaximum(1000000000)
|
||||
@ -240,7 +297,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.spinBox_BCG_back_JJIV_2 = QSpinBox(self.groupBox_4)
|
||||
self.spinBox_BCG_back_JJIV_2.setObjectName(u"spinBox_BCG_back_JJIV_2")
|
||||
self.spinBox_BCG_back_JJIV_2.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_BCG_back_JJIV_2.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_BCG_back_JJIV_2.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_BCG_back_JJIV_2.setFont(font2)
|
||||
self.spinBox_BCG_back_JJIV_2.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_BCG_back_JJIV_2.setMinimum(0)
|
||||
self.spinBox_BCG_back_JJIV_2.setMaximum(1000000000)
|
||||
@ -256,7 +315,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.spinBox_BCG_back_JJIV_1 = QSpinBox(self.groupBox_4)
|
||||
self.spinBox_BCG_back_JJIV_1.setObjectName(u"spinBox_BCG_back_JJIV_1")
|
||||
self.spinBox_BCG_back_JJIV_1.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_BCG_back_JJIV_1.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_BCG_back_JJIV_1.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_BCG_back_JJIV_1.setFont(font2)
|
||||
self.spinBox_BCG_back_JJIV_1.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_BCG_back_JJIV_1.setMinimum(0)
|
||||
self.spinBox_BCG_back_JJIV_1.setMaximum(1000000000)
|
||||
@ -265,27 +326,35 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.label_7 = QLabel(self.groupBox_4)
|
||||
self.label_7.setObjectName(u"label_7")
|
||||
self.label_7.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_7.sizePolicy().hasHeightForWidth())
|
||||
self.label_7.setSizePolicy(sizePolicy3)
|
||||
self.label_7.setFont(font2)
|
||||
self.label_7.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.gridLayout_3.addWidget(self.label_7, 1, 3, 1, 1)
|
||||
|
||||
self.label_5 = QLabel(self.groupBox_4)
|
||||
self.label_5.setObjectName(u"label_5")
|
||||
self.label_5.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_5.sizePolicy().hasHeightForWidth())
|
||||
self.label_5.setSizePolicy(sizePolicy3)
|
||||
self.label_5.setFont(font2)
|
||||
self.label_5.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.gridLayout_3.addWidget(self.label_5, 0, 3, 1, 1)
|
||||
|
||||
self.label_3 = QLabel(self.groupBox_4)
|
||||
self.label_3.setObjectName(u"label_3")
|
||||
self.label_3.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth())
|
||||
self.label_3.setSizePolicy(sizePolicy3)
|
||||
self.label_3.setFont(font2)
|
||||
|
||||
self.gridLayout_3.addWidget(self.label_3, 0, 1, 1, 1)
|
||||
|
||||
self.label_12 = QLabel(self.groupBox_4)
|
||||
self.label_12.setObjectName(u"label_12")
|
||||
self.label_12.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_12.sizePolicy().hasHeightForWidth())
|
||||
self.label_12.setSizePolicy(sizePolicy3)
|
||||
self.label_12.setFont(font2)
|
||||
|
||||
self.gridLayout_3.addWidget(self.label_12, 1, 1, 1, 1)
|
||||
|
||||
@ -303,7 +372,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.gridLayout_4.setObjectName(u"gridLayout_4")
|
||||
self.spinBox_ECG_front_RRIV_2 = QSpinBox(self.groupBox_3)
|
||||
self.spinBox_ECG_front_RRIV_2.setObjectName(u"spinBox_ECG_front_RRIV_2")
|
||||
self.spinBox_ECG_front_RRIV_2.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_ECG_front_RRIV_2.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_ECG_front_RRIV_2.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_ECG_front_RRIV_2.setFont(font2)
|
||||
self.spinBox_ECG_front_RRIV_2.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_ECG_front_RRIV_2.setMinimum(0)
|
||||
self.spinBox_ECG_front_RRIV_2.setMaximum(1000000000)
|
||||
@ -312,7 +383,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.label_10 = QLabel(self.groupBox_3)
|
||||
self.label_10.setObjectName(u"label_10")
|
||||
self.label_10.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_10.sizePolicy().hasHeightForWidth())
|
||||
self.label_10.setSizePolicy(sizePolicy3)
|
||||
self.label_10.setFont(font2)
|
||||
self.label_10.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.gridLayout_4.addWidget(self.label_10, 1, 3, 1, 1)
|
||||
@ -326,7 +399,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.spinBox_ECG_front_Signal_2 = QSpinBox(self.groupBox_3)
|
||||
self.spinBox_ECG_front_Signal_2.setObjectName(u"spinBox_ECG_front_Signal_2")
|
||||
self.spinBox_ECG_front_Signal_2.setEnabled(False)
|
||||
self.spinBox_ECG_front_Signal_2.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_ECG_front_Signal_2.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_ECG_front_Signal_2.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_ECG_front_Signal_2.setFont(font2)
|
||||
self.spinBox_ECG_front_Signal_2.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_ECG_front_Signal_2.setMinimum(0)
|
||||
self.spinBox_ECG_front_Signal_2.setMaximum(1000000000)
|
||||
@ -336,7 +411,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.spinBox_ECG_front_Signal_1 = QSpinBox(self.groupBox_3)
|
||||
self.spinBox_ECG_front_Signal_1.setObjectName(u"spinBox_ECG_front_Signal_1")
|
||||
self.spinBox_ECG_front_Signal_1.setEnabled(False)
|
||||
self.spinBox_ECG_front_Signal_1.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_ECG_front_Signal_1.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_ECG_front_Signal_1.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_ECG_front_Signal_1.setFont(font2)
|
||||
self.spinBox_ECG_front_Signal_1.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_ECG_front_Signal_1.setMinimum(0)
|
||||
self.spinBox_ECG_front_Signal_1.setMaximum(1000000000)
|
||||
@ -345,7 +422,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.spinBox_ECG_front_RRIV_1 = QSpinBox(self.groupBox_3)
|
||||
self.spinBox_ECG_front_RRIV_1.setObjectName(u"spinBox_ECG_front_RRIV_1")
|
||||
self.spinBox_ECG_front_RRIV_1.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_ECG_front_RRIV_1.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_ECG_front_RRIV_1.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_ECG_front_RRIV_1.setFont(font2)
|
||||
self.spinBox_ECG_front_RRIV_1.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_ECG_front_RRIV_1.setMinimum(0)
|
||||
self.spinBox_ECG_front_RRIV_1.setMaximum(1000000000)
|
||||
@ -354,20 +433,26 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.label_8 = QLabel(self.groupBox_3)
|
||||
self.label_8.setObjectName(u"label_8")
|
||||
self.label_8.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_8.sizePolicy().hasHeightForWidth())
|
||||
self.label_8.setSizePolicy(sizePolicy3)
|
||||
self.label_8.setFont(font2)
|
||||
self.label_8.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.gridLayout_4.addWidget(self.label_8, 0, 3, 1, 1)
|
||||
|
||||
self.label_13 = QLabel(self.groupBox_3)
|
||||
self.label_13.setObjectName(u"label_13")
|
||||
self.label_13.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_13.sizePolicy().hasHeightForWidth())
|
||||
self.label_13.setSizePolicy(sizePolicy3)
|
||||
self.label_13.setFont(font2)
|
||||
|
||||
self.gridLayout_4.addWidget(self.label_13, 0, 1, 1, 1)
|
||||
|
||||
self.label_14 = QLabel(self.groupBox_3)
|
||||
self.label_14.setObjectName(u"label_14")
|
||||
self.label_14.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_14.sizePolicy().hasHeightForWidth())
|
||||
self.label_14.setSizePolicy(sizePolicy3)
|
||||
self.label_14.setFont(font2)
|
||||
|
||||
self.gridLayout_4.addWidget(self.label_14, 1, 1, 1, 1)
|
||||
|
||||
@ -391,14 +476,18 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.label_11 = QLabel(self.groupBox_5)
|
||||
self.label_11.setObjectName(u"label_11")
|
||||
self.label_11.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_11.sizePolicy().hasHeightForWidth())
|
||||
self.label_11.setSizePolicy(sizePolicy3)
|
||||
self.label_11.setFont(font2)
|
||||
self.label_11.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.gridLayout_5.addWidget(self.label_11, 1, 3, 1, 1)
|
||||
|
||||
self.spinBox_ECG_back_RRIV_2 = QSpinBox(self.groupBox_5)
|
||||
self.spinBox_ECG_back_RRIV_2.setObjectName(u"spinBox_ECG_back_RRIV_2")
|
||||
self.spinBox_ECG_back_RRIV_2.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_ECG_back_RRIV_2.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_ECG_back_RRIV_2.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_ECG_back_RRIV_2.setFont(font2)
|
||||
self.spinBox_ECG_back_RRIV_2.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_ECG_back_RRIV_2.setMinimum(0)
|
||||
self.spinBox_ECG_back_RRIV_2.setMaximum(1000000000)
|
||||
@ -408,7 +497,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.spinBox_ECG_back_Signal_2 = QSpinBox(self.groupBox_5)
|
||||
self.spinBox_ECG_back_Signal_2.setObjectName(u"spinBox_ECG_back_Signal_2")
|
||||
self.spinBox_ECG_back_Signal_2.setEnabled(False)
|
||||
self.spinBox_ECG_back_Signal_2.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_ECG_back_Signal_2.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_ECG_back_Signal_2.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_ECG_back_Signal_2.setFont(font2)
|
||||
self.spinBox_ECG_back_Signal_2.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_ECG_back_Signal_2.setMinimum(0)
|
||||
self.spinBox_ECG_back_Signal_2.setMaximum(1000000000)
|
||||
@ -417,7 +508,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.spinBox_ECG_back_RRIV_1 = QSpinBox(self.groupBox_5)
|
||||
self.spinBox_ECG_back_RRIV_1.setObjectName(u"spinBox_ECG_back_RRIV_1")
|
||||
self.spinBox_ECG_back_RRIV_1.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_ECG_back_RRIV_1.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_ECG_back_RRIV_1.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_ECG_back_RRIV_1.setFont(font2)
|
||||
self.spinBox_ECG_back_RRIV_1.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_ECG_back_RRIV_1.setMinimum(0)
|
||||
self.spinBox_ECG_back_RRIV_1.setMaximum(1000000000)
|
||||
@ -427,7 +520,9 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.spinBox_ECG_back_Signal_1 = QSpinBox(self.groupBox_5)
|
||||
self.spinBox_ECG_back_Signal_1.setObjectName(u"spinBox_ECG_back_Signal_1")
|
||||
self.spinBox_ECG_back_Signal_1.setEnabled(False)
|
||||
self.spinBox_ECG_back_Signal_1.setFont(font)
|
||||
sizePolicy2.setHeightForWidth(self.spinBox_ECG_back_Signal_1.sizePolicy().hasHeightForWidth())
|
||||
self.spinBox_ECG_back_Signal_1.setSizePolicy(sizePolicy2)
|
||||
self.spinBox_ECG_back_Signal_1.setFont(font2)
|
||||
self.spinBox_ECG_back_Signal_1.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
|
||||
self.spinBox_ECG_back_Signal_1.setMinimum(0)
|
||||
self.spinBox_ECG_back_Signal_1.setMaximum(1000000000)
|
||||
@ -436,20 +531,26 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.label_9 = QLabel(self.groupBox_5)
|
||||
self.label_9.setObjectName(u"label_9")
|
||||
self.label_9.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_9.sizePolicy().hasHeightForWidth())
|
||||
self.label_9.setSizePolicy(sizePolicy3)
|
||||
self.label_9.setFont(font2)
|
||||
self.label_9.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.gridLayout_5.addWidget(self.label_9, 0, 3, 1, 1)
|
||||
|
||||
self.label_15 = QLabel(self.groupBox_5)
|
||||
self.label_15.setObjectName(u"label_15")
|
||||
self.label_15.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_15.sizePolicy().hasHeightForWidth())
|
||||
self.label_15.setSizePolicy(sizePolicy3)
|
||||
self.label_15.setFont(font2)
|
||||
|
||||
self.gridLayout_5.addWidget(self.label_15, 0, 1, 1, 1)
|
||||
|
||||
self.label_16 = QLabel(self.groupBox_5)
|
||||
self.label_16.setObjectName(u"label_16")
|
||||
self.label_16.setFont(font)
|
||||
sizePolicy3.setHeightForWidth(self.label_16.sizePolicy().hasHeightForWidth())
|
||||
self.label_16.setSizePolicy(sizePolicy3)
|
||||
self.label_16.setFont(font2)
|
||||
|
||||
self.gridLayout_5.addWidget(self.label_16, 1, 1, 1, 1)
|
||||
|
||||
@ -459,6 +560,42 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.verticalLayout_5.addWidget(self.groupBox_5)
|
||||
|
||||
self.groupBox_7 = QGroupBox(self.groupBox_args)
|
||||
self.groupBox_7.setObjectName(u"groupBox_7")
|
||||
self.horizontalLayout_6 = QHBoxLayout(self.groupBox_7)
|
||||
self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
|
||||
self.gridLayout_6 = QGridLayout()
|
||||
self.gridLayout_6.setObjectName(u"gridLayout_6")
|
||||
self.pushButton_getPos = QPushButton(self.groupBox_7)
|
||||
self.pushButton_getPos.setObjectName(u"pushButton_getPos")
|
||||
self.pushButton_getPos.setFont(font)
|
||||
|
||||
self.gridLayout_6.addWidget(self.pushButton_getPos, 2, 0, 1, 1)
|
||||
|
||||
self.pushButton_resetPos = QPushButton(self.groupBox_7)
|
||||
self.pushButton_resetPos.setObjectName(u"pushButton_resetPos")
|
||||
self.pushButton_resetPos.setFont(font)
|
||||
|
||||
self.gridLayout_6.addWidget(self.pushButton_resetPos, 2, 1, 1, 1)
|
||||
|
||||
self.checkBox_sync_xlim = QCheckBox(self.groupBox_7)
|
||||
self.checkBox_sync_xlim.setObjectName(u"checkBox_sync_xlim")
|
||||
self.checkBox_sync_xlim.setFont(font)
|
||||
self.checkBox_sync_xlim.setChecked(True)
|
||||
|
||||
self.gridLayout_6.addWidget(self.checkBox_sync_xlim, 0, 0, 1, 2)
|
||||
|
||||
self.label_19 = QLabel(self.groupBox_7)
|
||||
self.label_19.setObjectName(u"label_19")
|
||||
|
||||
self.gridLayout_6.addWidget(self.label_19, 1, 0, 1, 2)
|
||||
|
||||
|
||||
self.horizontalLayout_6.addLayout(self.gridLayout_6)
|
||||
|
||||
|
||||
self.verticalLayout_5.addWidget(self.groupBox_7)
|
||||
|
||||
self.verticalLayout_5.setStretch(0, 2)
|
||||
self.verticalLayout_5.setStretch(1, 2)
|
||||
self.verticalLayout_5.setStretch(2, 2)
|
||||
@ -467,10 +604,6 @@ class Ui_MainWindow_precisely_align(object):
|
||||
|
||||
self.verticalLayout.addWidget(self.groupBox_args)
|
||||
|
||||
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
|
||||
|
||||
self.verticalLayout.addItem(self.verticalSpacer)
|
||||
|
||||
self.horizontalLayout_8 = QHBoxLayout()
|
||||
self.horizontalLayout_8.setObjectName(u"horizontalLayout_8")
|
||||
self.pushButton_calculate_correlation = QPushButton(self.groupBox_left)
|
||||
@ -526,7 +659,8 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.verticalLayout.addWidget(self.groupBox)
|
||||
|
||||
self.verticalLayout.setStretch(0, 1)
|
||||
self.verticalLayout.setStretch(1, 7)
|
||||
self.verticalLayout.setStretch(1, 1)
|
||||
self.verticalLayout.setStretch(2, 6)
|
||||
self.verticalLayout.setStretch(3, 1)
|
||||
self.verticalLayout.setStretch(4, 1)
|
||||
self.verticalLayout.setStretch(5, 5)
|
||||
@ -551,6 +685,10 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.action.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u52a0\u8f7d\u5b58\u6863", None))
|
||||
self.groupBox_canvas.setTitle(QCoreApplication.translate("MainWindow_precisely_align", u"\u7ed8\u56fe\u533a", None))
|
||||
self.groupBox_left.setTitle(QCoreApplication.translate("MainWindow_precisely_align", u"\u6570\u636e\u7cbe\u540c\u6b65", None))
|
||||
self.label_18.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u7f16\u53f7\uff1a", None))
|
||||
self.label_sampno.setText(QCoreApplication.translate("MainWindow_precisely_align", u"None", None))
|
||||
self.label_20.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u504f\u79fb\u91cf\uff1a", None))
|
||||
self.label_pos.setText(QCoreApplication.translate("MainWindow_precisely_align", u"0", None))
|
||||
self.pushButton_input_setting.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u5bfc\u5165\u8bbe\u7f6e", None))
|
||||
self.pushButton_input.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u5f00\u59cb\u5bfc\u5165", None))
|
||||
self.groupBox_args.setTitle(QCoreApplication.translate("MainWindow_precisely_align", u"\u53c2\u6570\u8f93\u5165", None))
|
||||
@ -581,6 +719,11 @@ class Ui_MainWindow_precisely_align(object):
|
||||
self.label_9.setText(QCoreApplication.translate("MainWindow_precisely_align", u"~", None))
|
||||
self.label_15.setText(QCoreApplication.translate("MainWindow_precisely_align", u"RRIV\u5e8f\u53f7", None))
|
||||
self.label_16.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u4fe1\u53f7\u5750\u6807", None))
|
||||
self.groupBox_7.setTitle(QCoreApplication.translate("MainWindow_precisely_align", u"\u504f\u79fb\u91cf\u8c03\u6574", None))
|
||||
self.pushButton_getPos.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u6355\u83b7\u5f53\u524d\u504f\u79fb\u91cf", None))
|
||||
self.pushButton_resetPos.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u6062\u590d\u9ed8\u8ba4\u504f\u79fb\u91cf", None))
|
||||
self.checkBox_sync_xlim.setText(QCoreApplication.translate("MainWindow_precisely_align", u"X\u8f74\u540c\u6b65\uff08\u4ec5\u5728\u9009\u5b9a\u533a\u95f4\u65f6\u6709\u6548\uff09", None))
|
||||
self.label_19.setText(QCoreApplication.translate("MainWindow_precisely_align", u"Tips: \u91cd\u65b0\u6355\u83b7\u65f6\u5c06\u5bf9\u9f50\u70b9\u7f6e\u4e8ex\u8f74\u5de6\u4fa7\uff0c\u8ba1\u7b97x\u8f74\u8d77\u70b9\u5dee\u503c", None))
|
||||
self.pushButton_calculate_correlation.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u8ba1\u7b97\u76f8\u5173\u6027", None))
|
||||
self.pushButton_correlation_align.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u76f8\u5173\u5bf9\u9f50", None))
|
||||
self.pushButton_view_align.setText(QCoreApplication.translate("MainWindow_precisely_align", u"\u67e5\u770b\u5bf9\u9f50\u7ed3\u679c", None))
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
<width>1912</width>
|
||||
<height>1061</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -56,7 +56,65 @@
|
||||
<property name="title">
|
||||
<string>数据精同步</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,7,0,1,1,5">
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,1,6,1,1,5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>编号:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_sampno">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>偏移量:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_pos">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
@ -102,7 +160,7 @@
|
||||
<property name="title">
|
||||
<string>参数输入</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="2,2,2,2,2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="2,2,2,2,2,0">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_6">
|
||||
<property name="title">
|
||||
@ -177,9 +235,15 @@
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -195,9 +259,15 @@
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QSpinBox" name="spinBox_BCG_front_JJIV_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -228,9 +298,15 @@
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -246,9 +322,15 @@
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -264,9 +346,15 @@
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QSpinBox" name="spinBox_BCG_front_JJIV_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -282,9 +370,15 @@
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -297,9 +391,15 @@
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -309,9 +409,15 @@
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -337,9 +443,15 @@
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -358,9 +470,15 @@
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -376,9 +494,15 @@
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QSpinBox" name="spinBox_BCG_back_JJIV_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -409,9 +533,15 @@
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QSpinBox" name="spinBox_BCG_back_JJIV_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -427,9 +557,15 @@
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -442,9 +578,15 @@
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -457,9 +599,15 @@
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -469,9 +617,15 @@
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -494,9 +648,15 @@
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="4">
|
||||
<widget class="QSpinBox" name="spinBox_ECG_front_RRIV_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -512,9 +672,15 @@
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -542,9 +708,15 @@
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -563,9 +735,15 @@
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -581,9 +759,15 @@
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QSpinBox" name="spinBox_ECG_front_RRIV_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -599,9 +783,15 @@
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -614,9 +804,15 @@
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -626,9 +822,15 @@
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -663,9 +865,15 @@
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -678,9 +886,15 @@
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QSpinBox" name="spinBox_ECG_back_RRIV_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -699,9 +913,15 @@
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -717,9 +937,15 @@
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QSpinBox" name="spinBox_ECG_back_RRIV_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -738,9 +964,15 @@
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
@ -756,9 +988,15 @@
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -771,9 +1009,15 @@
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -783,9 +1027,15 @@
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -798,22 +1048,68 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_7">
|
||||
<property name="title">
|
||||
<string>偏移量调整</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="pushButton_getPos">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>捕获当前偏移量</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="pushButton_resetPos">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>恢复默认偏移量</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkBox_sync_xlim">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>X轴同步(仅在选定区间时有效)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>Tips: 重新捕获时将对齐点置于x轴左侧,计算x轴起点差值</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
|
||||
Reference in New Issue
Block a user