Initial Commit.
This commit is contained in:
8
.gitignore
vendored
8
.gitignore
vendored
@ -247,3 +247,11 @@ fabric.properties
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
env_signal_label/
|
||||
logs/*
|
||||
config/*
|
||||
func/detect_Jpeak_model/*
|
||||
.idea/*
|
||||
!./logs
|
||||
!./config
|
||||
!./func/detect_Jpeak_model
|
||||
198
func/BCGDataset/Dataset_operation.py
Normal file
198
func/BCGDataset/Dataset_operation.py
Normal file
@ -0,0 +1,198 @@
|
||||
# encoding:utf-8
|
||||
import warnings
|
||||
from os import listdir
|
||||
|
||||
from numpy import array, arange, zeros, percentile, append, full
|
||||
from numpy import max as np_max
|
||||
from numpy import max as np_min
|
||||
from pandas import read_csv, DataFrame, concat
|
||||
from scipy.signal import butter, filtfilt
|
||||
from torch.utils.data import Dataset
|
||||
warnings.filterwarnings("ignore")
|
||||
|
||||
class BCGDataset(Dataset):
|
||||
def __init__(self, train=True):
|
||||
if train:
|
||||
self.data = array(read_csv("./in_data/train.txt").iloc[:,arange(1000)])
|
||||
self.label = array(read_csv("./in_data/train.txt").iloc[:,arange(1000,2000)])
|
||||
else:
|
||||
self.data = array(read_csv("./in_data/test.txt").iloc[:, arange(1000)])
|
||||
self.label = array(read_csv("./in_data/test.txt").iloc[:, arange(1000, 2000)])
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self.data[index], self.label[index]
|
||||
|
||||
def __len__(self):
|
||||
return len(self.label)
|
||||
|
||||
class BCG_Operation():
|
||||
def __init__(self, sample_rate=1000):
|
||||
self.sample_rate = sample_rate
|
||||
|
||||
def down_sample(self,data=None, down_radio=10):
|
||||
if data is None:
|
||||
raise ValueError("data is None, please given an real value!")
|
||||
length_before = len(data)
|
||||
length_after = length_before//down_radio
|
||||
data = data[:length_after*down_radio]
|
||||
data = data.reshape(-1,down_radio)
|
||||
data = data[:,0]
|
||||
self.sample_rate = self.sample_rate/down_radio
|
||||
return data
|
||||
|
||||
def Splitwin(self, data=None, len_win=None, coverage=1.0,calculate_to_end=False):
|
||||
"""
|
||||
分窗
|
||||
:param len_win: length of window
|
||||
:return: signal windows
|
||||
"""
|
||||
if ( len_win is None) or (data is None):
|
||||
raise ValueError("length of window or data is None, please given an real value!")
|
||||
else:
|
||||
length = len_win * self.sample_rate # number point of a window
|
||||
# step of split windows
|
||||
step = length*coverage
|
||||
start = 0
|
||||
Splitdata = []
|
||||
while (len(data)-start>=length):
|
||||
Splitdata.append( data[int(start):int(start+length)] )
|
||||
start += step
|
||||
if calculate_to_end and (len(data)-start>2000):
|
||||
remain = len(data)-start
|
||||
start = start - step
|
||||
step = int(remain/2000)
|
||||
start = start + step*2000
|
||||
Splitdata.append(data[int(start):int(start+length)])
|
||||
return array(Splitdata), step
|
||||
elif calculate_to_end :
|
||||
return array(Splitdata), 0
|
||||
else:
|
||||
return array(Splitdata)
|
||||
|
||||
def Butterworth(self,data, type, low_cut = 0.0, high_cut = 0.0, order = 10):
|
||||
"""
|
||||
:param type: Type of Butter. filter, lowpass, bandpass, ...
|
||||
:param lowcut: Low cutoff frequency
|
||||
:param highcut: High cutoff frequency
|
||||
:param order: Order of filter
|
||||
:return: Signal after filtering
|
||||
"""
|
||||
if type == "lowpass": # 低通滤波处理
|
||||
b, a = butter(order, low_cut / (self.sample_rate * 0.5), btype='lowpass')
|
||||
return filtfilt(b, a, array(data))
|
||||
elif type == "bandpass": # 带通滤波处理
|
||||
low = low_cut / (self.sample_rate * 0.5)
|
||||
high = high_cut / (self.sample_rate * 0.5)
|
||||
b, a = butter(order, [low, high], btype='bandpass')
|
||||
return filtfilt(b, a, array(data))
|
||||
elif type == "highpass": # 高通滤波处理
|
||||
b, a = butter(order, high_cut / (self.sample_rate * 0.5), btype='highpass')
|
||||
return filtfilt(b, a, array(data))
|
||||
else: # 警告,滤波器类型必须有
|
||||
raise ValueError("Please choose a type of fliter")
|
||||
|
||||
def AmpMovement(self, data, win_size, threshold=20, get_judge_line=False):
|
||||
"""
|
||||
基于幅值方法检测体动:
|
||||
1.将输入信号按win_size切分
|
||||
2.将每个win_size信号片段分窗,每个窗2s,步长为2s
|
||||
3.计算一分钟所有信号窗的最大峰谷值差,获取中位数和均值
|
||||
4.所有2s时间窗内,大于中位数/均值的2.2倍视为体动
|
||||
5.体动间间隔过短的信号,同样标记为体动
|
||||
:param data: Input signal
|
||||
:param win_size: Size of the win(Must be a multiple of 2)
|
||||
:return: State of signal
|
||||
"""
|
||||
Dataframe, cover_num = self.Splitwin(data, len_win=win_size, coverage=1.0, calculate_to_end=True)
|
||||
state_all = array([])
|
||||
Amp_list = array([])
|
||||
for win in range(Dataframe.shape[0]):
|
||||
state = array([])
|
||||
# two seconds window
|
||||
data_win = self.Splitwin(Dataframe[win], len_win=2, coverage=1.0)
|
||||
Amp = zeros(data_win.shape[0])
|
||||
for i in range(data_win.shape[0]):
|
||||
Amp[i] = np_max(data_win[i]) - np_min(data_win[i]) # max - min
|
||||
# 取..位数
|
||||
Median_Amp = percentile(Amp, 20) # 20%
|
||||
if get_judge_line:
|
||||
Amp_list = append(Amp_list, full(win_size * self.sample_rate, 2.3 * Median_Amp))
|
||||
|
||||
for i in range(len(Amp)):
|
||||
if (Amp[i] > 2.1 * Median_Amp):
|
||||
state = append(state, "Movement")
|
||||
elif Amp[i] < threshold:
|
||||
state = append(state, "Nobody")
|
||||
else:
|
||||
state = append(state, "Sleep")
|
||||
|
||||
if win == Dataframe.shape[0] - 1 and cover_num > 0:
|
||||
state = state[-int(cover_num):]
|
||||
|
||||
state_all = append(state_all, state)
|
||||
|
||||
if get_judge_line:
|
||||
return state_all, Amp_list
|
||||
else:
|
||||
return state_all
|
||||
|
||||
def preprocess1(self):
|
||||
# ----------------------------------------------------------
|
||||
data_dir = "../in_data/"
|
||||
dir_list = listdir(data_dir)
|
||||
|
||||
data_list = [data_dir + dir + "/orgData.txt" for dir in dir_list]
|
||||
label_list = [data_dir + dir + "/label.txt" for dir in dir_list]
|
||||
print(data_list)
|
||||
print(label_list)
|
||||
for i in range(len(data_list)):
|
||||
orgBCG = array(read_csv(data_list[i], header=None)).reshape(-1)
|
||||
orgLabel = array(read_csv(label_list[i])).reshape(-1)
|
||||
|
||||
# ---------------------Movement Detection-------------------------
|
||||
operation = BCG_Operation()
|
||||
BCG = operation.Butterworth(data=orgBCG, type="bandpass", low_cut=2.5, high_cut=10, order=2)
|
||||
state_win60 = operation.AmpMovement(orgBCG, win_size=60)
|
||||
|
||||
visual_state = array([])
|
||||
for num in range(state_win60.shape[0]):
|
||||
print("state_num/all_state: ", num, '/', state_win60.shape[0])
|
||||
if state_win60[num] == "Movement":
|
||||
visual_state = append(visual_state, full(2000, 1))
|
||||
else:
|
||||
visual_state = append(visual_state, full(2000, 0))
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
downBCG = operation.down_sample(data=orgBCG, down_radio=10)
|
||||
downLabel = operation.down_sample(data=orgLabel, down_radio=10)
|
||||
downState = operation.down_sample(data=visual_state, down_radio=10)
|
||||
|
||||
length_before = len(downState)
|
||||
length_after = length_before // 1000
|
||||
downBCG = downBCG[:length_after * 1000]
|
||||
downLabel = downLabel[:length_after * 1000]
|
||||
downState = downState[:length_after * 1000]
|
||||
|
||||
downBCG = downBCG.reshape(-1, 1000)
|
||||
downLabel = downLabel.reshape(-1, 1000)
|
||||
downState = downState.reshape(-1, 1000)
|
||||
downState = np_max(downState, axis=1)
|
||||
|
||||
df_BCG = DataFrame(downBCG)
|
||||
df_label = DataFrame(downLabel)
|
||||
df_state = DataFrame(downState, columns=["state"])
|
||||
df_BCG.to_csv()
|
||||
|
||||
df_all = concat([df_BCG, df_label, df_state], axis=1)
|
||||
df_all.to_csv(data_dir + "/data" + str(i + 1) + ".txt", index=False)
|
||||
|
||||
def read_all_data(data_dir):
|
||||
df_all = read_csv(data_dir)
|
||||
df_clean = df_all[ df_all["state"]==0.0 ]
|
||||
df_artifact = df_all[ df_all["state"]==1.0 ]
|
||||
data_clean = df_clean.iloc[:,arange(1000)]
|
||||
label_clean = df_clean.iloc[:,arange(1000,2000)]
|
||||
data_artifact = df_artifact.iloc[:,arange(1000)]
|
||||
label_artifact = df_artifact.iloc[:,arange(1000,2000)]
|
||||
|
||||
return array(data_clean),array(label_clean),array(data_artifact),array(label_artifact)
|
||||
1
func/BCGDataset/__init__.py
Normal file
1
func/BCGDataset/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .Dataset_operation import BCGDataset,BCG_Operation,read_all_data
|
||||
1744
func/Deep_Model/Unet.py
Normal file
1744
func/Deep_Model/Unet.py
Normal file
File diff suppressed because it is too large
Load Diff
1
func/Deep_Model/__init__.py
Normal file
1
func/Deep_Model/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .Unet import Unet,ResUNet,DUNet,LSTM_UNet,R2U_Net,AttU_Net,R2AttU_Net,Unet_lstm,deep_Unet,Fivelayer_Unet,Fourlayer_LUnet,Sixlayer_Unet,Threelayer_Unet,Sixlayer_Lstm_Unet,Fivelayer_Lstm_Unet,Fourlayer_Lstm_Unet
|
||||
56
func/Filters/Preprocessing.py
Normal file
56
func/Filters/Preprocessing.py
Normal file
@ -0,0 +1,56 @@
|
||||
# encoding:utf-8
|
||||
|
||||
"""
|
||||
@ date: 2020-09-16
|
||||
@ author: jingxian
|
||||
@ illustration: Pre-processing
|
||||
"""
|
||||
from matplotlib import pyplot as plt
|
||||
from numpy import array
|
||||
from pandas import read_csv
|
||||
from scipy.signal import butter, filtfilt, sosfiltfilt
|
||||
|
||||
|
||||
def Butterworth_for_ECG_PreProcess(data, sample_rate, type, low_cut=0.0, high_cut=0.0, order=10):
|
||||
"""
|
||||
:param type: Type of Butter. filter, lowpass, bandpass, ...
|
||||
:param lowcut: Low cutoff frequency
|
||||
:param highcut: High cutoff frequency
|
||||
:param order: Order of filter
|
||||
:return: Signal after filtering
|
||||
"""
|
||||
if type == "lowpass": # 低通滤波处理
|
||||
b, a = butter(order, low_cut / (sample_rate * 0.5), btype='lowpass', output='ba')
|
||||
return filtfilt(b, a, data)
|
||||
elif type == "bandpass": # 带通滤波处理
|
||||
low = low_cut / (sample_rate * 0.5)
|
||||
high = high_cut / (sample_rate * 0.5)
|
||||
b, a = butter(order, [low, high], btype='bandpass', output='ba')
|
||||
return filtfilt(b, a, data)
|
||||
elif type == "highpass": # 高通滤波处理
|
||||
b, a = butter(order, high_cut / (sample_rate * 0.5), btype='highpass', output='ba')
|
||||
return filtfilt(b, a, data)
|
||||
else: # 警告,滤波器类型必须有
|
||||
raise ValueError("Please choose a type of fliter")
|
||||
|
||||
def Butterworth_for_BCG_PreProcess(data, sample_rate, type, low_cut=0.0, high_cut=0.0, order=10):
|
||||
"""
|
||||
:param type: Type of Butter. filter, lowpass, bandpass, ...
|
||||
:param lowcut: Low cutoff frequency
|
||||
:param highcut: High cutoff frequency
|
||||
:param order: Order of filter
|
||||
:return: Signal after filtering
|
||||
"""
|
||||
if type == "lowpass": # 低通滤波处理
|
||||
sos = butter(order, low_cut / (sample_rate * 0.5), btype='lowpass', output='sos')
|
||||
return sosfiltfilt(sos, array(data))
|
||||
elif type == "bandpass": # 带通滤波处理
|
||||
low = low_cut / (sample_rate * 0.5)
|
||||
high = high_cut / (sample_rate * 0.5)
|
||||
sos = butter(order, [low, high], btype='bandpass', output='sos')
|
||||
return sosfiltfilt(sos, array(data))
|
||||
elif type == "highpass": # 高通滤波处理
|
||||
sos = butter(order, high_cut / (sample_rate * 0.5), btype='highpass', output='sos')
|
||||
return sosfiltfilt(sos, array(data))
|
||||
else: # 警告,滤波器类型必须有
|
||||
raise ValueError("Please choose a type of fliter")
|
||||
584
func/Module_detect_Jpeak.py
Normal file
584
func/Module_detect_Jpeak.py
Normal file
@ -0,0 +1,584 @@
|
||||
from gc import collect
|
||||
from pathlib import Path
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from PySide6.QtWidgets import QMessageBox, QMainWindow, QWidget, QPushButton, QProgressBar, QApplication
|
||||
from matplotlib import gridspec
|
||||
from matplotlib.backends.backend_qt import NavigationToolbar2QT
|
||||
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
|
||||
from overrides import overrides
|
||||
from pandas import read_csv, DataFrame
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.utils.detect_Jpeak import preprocess, Jpeak_Detection
|
||||
|
||||
from ui.MainWindow.MainWindow_detect_Jpeak import Ui_MainWindow_detect_Jpeak
|
||||
from ui.setting.detect_Jpeak_input_setting import Ui_MainWindow_detect_Jpeak_input_setting
|
||||
|
||||
|
||||
Config = {
|
||||
|
||||
}
|
||||
|
||||
ButtonState = {
|
||||
"Default": {
|
||||
"pushButton_input_setting": True,
|
||||
"pushButton_input": True,
|
||||
"pushButton_view": False,
|
||||
"pushButton_save": False
|
||||
},
|
||||
"Current": {
|
||||
"pushButton_input_setting": True,
|
||||
"pushButton_input": True,
|
||||
"pushButton_view": False,
|
||||
"pushButton_save": False
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SettingWindow(QMainWindow):
|
||||
|
||||
def __init__(self, root_path, sampID):
|
||||
|
||||
super(SettingWindow, self).__init__()
|
||||
self.ui = Ui_MainWindow_detect_Jpeak_input_setting()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
self.root_path = root_path
|
||||
self.sampID = sampID
|
||||
|
||||
self.config = None
|
||||
self.__read_config__()
|
||||
|
||||
self.ui.spinBox_input_freq.valueChanged.connect(self.__update_ui__)
|
||||
self.ui.pushButton_confirm.clicked.connect(self.__write_config__)
|
||||
self.ui.pushButton_cancel.clicked.connect(self.__rollback_config__)
|
||||
self.ui.pushButton_cancel.clicked.connect(self.close)
|
||||
|
||||
def __read_config__(self):
|
||||
|
||||
|
||||
if not Path(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.DETECT_JPEAK_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
self.config = file_config
|
||||
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) / Path(ConfigParams.DETECT_JPEAK_INPUT_BCG_FILENAME +
|
||||
str(Config["InputConfig"]["Freq"]) +
|
||||
ConfigParams.ENDSWITH_TXT))),
|
||||
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) / Path(ConfigParams.DETECT_JPEAK_SAVE_FILENAME +
|
||||
ConfigParams.ENDSWITH_TXT)))
|
||||
}
|
||||
})
|
||||
|
||||
# 数据回显
|
||||
self.ui.spinBox_input_freq.setValue(Config["InputConfig"]["Freq"])
|
||||
self.ui.plainTextEdit_file_path_input.setPlainText(Config["Path"]["Input"])
|
||||
self.ui.plainTextEdit_deepmodel_path.setPlainText(Config["ModelFolderPath"])
|
||||
self.ui.plainTextEdit_file_path_save.setPlainText(Config["Path"]["Save"])
|
||||
|
||||
def __write_config__(self):
|
||||
|
||||
# 从界面写入配置
|
||||
Config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
|
||||
Config["Path"]["Input"] = self.ui.plainTextEdit_file_path_input.toPlainText()
|
||||
Config["Path"]["Save"] = self.ui.plainTextEdit_file_path_save.toPlainText()
|
||||
Config["ModelFolderPath"] = self.ui.plainTextEdit_deepmodel_path.toPlainText()
|
||||
|
||||
# 保存配置到文件
|
||||
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
|
||||
self.config["ModelFolderPath"] = self.ui.plainTextEdit_deepmodel_path.toPlainText()
|
||||
|
||||
with open(ConfigParams.DETECT_JPEAK_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(self.config, f)
|
||||
|
||||
self.close()
|
||||
|
||||
def __rollback_config__(self):
|
||||
|
||||
self.__read_config__()
|
||||
|
||||
def __update_ui__(self):
|
||||
|
||||
self.ui.plainTextEdit_file_path_input.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.DETECT_JPEAK_INPUT_BCG_FILENAME +
|
||||
str(self.ui.spinBox_input_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
|
||||
class MainWindow_detect_Jpeak(QMainWindow):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
super(MainWindow_detect_Jpeak, self).__init__()
|
||||
self.ui = Ui_MainWindow_detect_Jpeak()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
self.root_path = None
|
||||
self.sampID = None
|
||||
|
||||
self.data = None
|
||||
self.model = None
|
||||
|
||||
self.setting = None
|
||||
|
||||
# 初始化进度条
|
||||
self.progressbar = None
|
||||
self.add_progressbar()
|
||||
|
||||
#初始化画框
|
||||
self.fig = None
|
||||
self.canvas = None
|
||||
self.figToolbar = None
|
||||
self.gs = None
|
||||
self.ax0 = None
|
||||
|
||||
self.line_data = None
|
||||
self.point_peak = None
|
||||
self.line_interval = None
|
||||
|
||||
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
|
||||
|
||||
self.setting = SettingWindow(root_path, sampID)
|
||||
|
||||
# 初始化画框
|
||||
self.fig = plt.figure(figsize=(12, 9), dpi=100)
|
||||
self.canvas = FigureCanvasQTAgg(self.fig)
|
||||
self.figToolbar = NavigationToolbar2QT(self.canvas)
|
||||
for action in self.figToolbar.actions():
|
||||
if action.text() == "Subplots" or action.text() == "Customize":
|
||||
self.figToolbar.removeAction(action)
|
||||
self.ui.verticalLayout_canvas.addWidget(self.canvas)
|
||||
self.ui.verticalLayout_canvas.addWidget(self.figToolbar)
|
||||
self.gs = gridspec.GridSpec(1, 1, height_ratios=[1])
|
||||
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
|
||||
self.ax0 = self.fig.add_subplot(self.gs[0])
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
|
||||
self.__resetAllButton__()
|
||||
|
||||
self.ui.doubleSpinBox_bandPassLow.setValue(Config["Filter"]["BandPassLow"])
|
||||
self.ui.doubleSpinBox_bandPassHigh.setValue(Config["Filter"]["BandPassHigh"])
|
||||
self.ui.spinBox_peaksValue.setValue(Config["PeaksValue"])
|
||||
self.ui.doubleSpinBox_ampValue.setValue(Config["AmpValue"])
|
||||
self.ui.spinBox_intervalLow.setValue(Config["IntervalLow"])
|
||||
self.ui.spinBox_intervalHigh.setValue(Config["IntervalHigh"])
|
||||
self.ui.checkBox_useCPU.setChecked(Config["UseCPU"])
|
||||
|
||||
self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__)
|
||||
self.ui.pushButton_input_setting.clicked.connect(self.setting.show)
|
||||
self.ui.pushButton_view.clicked.connect(self.__slot_btn_view__)
|
||||
self.ui.pushButton_save.clicked.connect(self.__slot_btn_save__)
|
||||
self.ui.doubleSpinBox_bandPassLow.editingFinished.connect(self.__update_config__)
|
||||
self.ui.doubleSpinBox_bandPassHigh.editingFinished.connect(self.__update_config__)
|
||||
self.ui.spinBox_peaksValue.editingFinished.connect(self.__update_config__)
|
||||
self.ui.doubleSpinBox_ampValue.editingFinished.connect(self.__update_config__)
|
||||
self.ui.spinBox_intervalLow.editingFinished.connect(self.__update_config__)
|
||||
self.ui.spinBox_intervalHigh.editingFinished.connect(self.__update_config__)
|
||||
self.ui.checkBox_useCPU.stateChanged.connect(self.__update_config__)
|
||||
self.ui.comboBox_model.currentTextChanged.connect(self.__update_config__)
|
||||
|
||||
@overrides
|
||||
def closeEvent(self, event):
|
||||
|
||||
self.__disableAllButton__()
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
|
||||
QApplication.processEvents()
|
||||
|
||||
# 清空画框
|
||||
if self.line_data and self.point_peak:
|
||||
del self.line_data
|
||||
del self.point_peak
|
||||
del self.line_interval
|
||||
self.canvas.draw()
|
||||
|
||||
# 释放资源
|
||||
del self.data
|
||||
del self.model
|
||||
self.fig.clf()
|
||||
plt.close(self.fig)
|
||||
self.deleteLater()
|
||||
collect()
|
||||
self.canvas = None
|
||||
event.accept()
|
||||
|
||||
@staticmethod
|
||||
def __reset__():
|
||||
|
||||
ButtonState["Current"].update(ButtonState["Default"].copy())
|
||||
ButtonState["Current"]["pushButton_view"] = True
|
||||
|
||||
def __plot__(self):
|
||||
|
||||
# 清空画框
|
||||
if self.line_data and self.point_peak and self.line_interval:
|
||||
try:
|
||||
self.line_data.remove()
|
||||
self.point_peak.remove()
|
||||
self.line_interval.remove()
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
sender = self.sender()
|
||||
|
||||
if sender == self.ui.pushButton_view:
|
||||
self.line_data, = self.ax0.plot(self.data.processed_data,
|
||||
color=Constants.PLOT_COLOR_BLUE,
|
||||
label=Constants.DETECT_J_PEAK_PLOT_LABEL_BCG)
|
||||
self.point_peak, = self.ax0.plot(self.data.peak, self.data.processed_data[self.data.peak],
|
||||
'r.',
|
||||
label=Constants.DETECT_J_PEAK_PLOT_LABEL_J_PEAKS)
|
||||
self.line_interval, = self.ax0.plot(self.data.interval,
|
||||
color=Constants.PLOT_COLOR_ORANGE,
|
||||
label=Constants.DETECT_J_PEAK_PLOT_LABEL_INTERVAL)
|
||||
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
|
||||
status = True
|
||||
info = Constants.DRAWING_FINISHED
|
||||
else:
|
||||
status = False
|
||||
info = Constants.DRAWING_FAILURE
|
||||
|
||||
self.canvas.draw()
|
||||
return status, info
|
||||
|
||||
def __disableAllButton__(self):
|
||||
# 禁用所有按钮
|
||||
all_widgets = self.centralWidget().findChildren(QWidget)
|
||||
|
||||
# 迭代所有部件,查找按钮并禁用它们
|
||||
for widget in all_widgets:
|
||||
if isinstance(widget, QPushButton):
|
||||
if widget.objectName() in ButtonState["Current"].keys():
|
||||
widget.setEnabled(False)
|
||||
|
||||
def __enableAllButton__(self):
|
||||
# 启用按钮
|
||||
all_widgets = self.centralWidget().findChildren(QWidget)
|
||||
|
||||
# 迭代所有部件,查找按钮并启用它们
|
||||
for widget in all_widgets:
|
||||
if isinstance(widget, QPushButton):
|
||||
if widget.objectName() in ButtonState["Current"].keys():
|
||||
widget.setEnabled(ButtonState["Current"][widget.objectName()])
|
||||
|
||||
def __resetAllButton__(self):
|
||||
# 启用按钮
|
||||
all_widgets = self.centralWidget().findChildren(QWidget)
|
||||
|
||||
# 迭代所有部件,查找按钮并启用它们
|
||||
for widget in all_widgets:
|
||||
if isinstance(widget, QPushButton):
|
||||
if widget.objectName() in ButtonState["Default"].keys():
|
||||
widget.setEnabled(ButtonState["Default"][widget.objectName()])
|
||||
|
||||
def __slot_btn_input__(self):
|
||||
|
||||
self.__disableAllButton__()
|
||||
|
||||
# 清空画框
|
||||
if self.line_data and self.point_peak and self.line_interval:
|
||||
try:
|
||||
self.line_data.remove()
|
||||
self.point_peak.remove()
|
||||
self.line_interval.remove()
|
||||
except ValueError:
|
||||
pass
|
||||
self.canvas.draw()
|
||||
|
||||
# 清空模型列表
|
||||
self.ui.comboBox_model.clear()
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.LOADING_MODEL))
|
||||
self.progressbar.setValue(0)
|
||||
QApplication.processEvents()
|
||||
|
||||
# 寻找模型
|
||||
self.model = Model()
|
||||
status, info = self.model.seek_model()
|
||||
if not status:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
|
||||
self.finish_operation()
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
self.update_ui_comboBox_model(self.model.model_list)
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.INPUTTING_DATA))
|
||||
self.progressbar.setValue(10)
|
||||
QApplication.processEvents()
|
||||
|
||||
# 导入数据
|
||||
self.data = Data()
|
||||
status, info = self.data.open_file()
|
||||
if not status:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
|
||||
self.finish_operation()
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
MainWindow_detect_Jpeak.__reset__()
|
||||
self.finish_operation()
|
||||
|
||||
def __slot_btn_view__(self):
|
||||
|
||||
self.__disableAllButton__()
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.DETECT_JPEAK_PROCESSING_DATA))
|
||||
self.progressbar.setValue(0)
|
||||
QApplication.processEvents()
|
||||
|
||||
# 数据预处理
|
||||
status, info = self.data.preprocess()
|
||||
if not status:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
|
||||
self.finish_operation()
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.DETECT_JPEAK_PREDICTING_PEAK))
|
||||
self.progressbar.setValue(10)
|
||||
QApplication.processEvents()
|
||||
|
||||
# 预测峰值
|
||||
self.model.selected_model = Config["DetectMethod"]
|
||||
status, info = self.data.predict_Jpeak(self.model)
|
||||
if not status:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
|
||||
self.finish_operation()
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.text_output(self.ui, Constants.DETECT_J_PEAK_DATA_LENGTH_POINTS + str(len(self.data.data)),
|
||||
Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.text_output(self.ui, Constants.DETECT_J_PEAK_DURATION_MIN +
|
||||
str((len(self.data.data) / Config["InputConfig"]["Freq"] / 60)),
|
||||
Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.text_output(self.ui, Constants.DETECT_J_PEAK_JPEAK_AMOUNT + str(len(self.data.peak)),
|
||||
Constants.TIPS_TYPE_INFO)
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.DRAWING_DATA))
|
||||
self.progressbar.setValue(70)
|
||||
QApplication.processEvents()
|
||||
|
||||
# 绘图
|
||||
status, info = self.__plot__()
|
||||
if not status:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
|
||||
self.finish_operation()
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
ButtonState["Current"]["pushButton_save"] = True
|
||||
self.finish_operation()
|
||||
|
||||
def __slot_btn_save__(self):
|
||||
|
||||
reply = QMessageBox.question(self, Constants.QUESTION_TITLE,
|
||||
Constants.QUESTION_CONTENT + Config["Path"]["Save"],
|
||||
QMessageBox.Yes | QMessageBox.No,
|
||||
QMessageBox.Yes)
|
||||
if reply == QMessageBox.Yes:
|
||||
self.__disableAllButton__()
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.SAVING_DATA))
|
||||
self.progressbar.setValue(0)
|
||||
QApplication.processEvents()
|
||||
|
||||
# 保存
|
||||
# status, info = self.data.save()
|
||||
total_rows = len(DataFrame(self.data.peak.reshape(-1)))
|
||||
chunk_size = ConfigParams.PREPROCESS_SAVE_CHUNK_SIZE
|
||||
with open(Config["Path"]["Save"], 'w') as f:
|
||||
for start in range(0, total_rows, chunk_size):
|
||||
end = min(start + chunk_size, total_rows)
|
||||
chunk = DataFrame(self.data.peak.reshape(-1)).iloc[start:end]
|
||||
status, info = self.data.save(chunk)
|
||||
progress = int((end / total_rows) * 100)
|
||||
self.progressbar.setValue(progress)
|
||||
QApplication.processEvents()
|
||||
|
||||
if not status:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
|
||||
self.finish_operation()
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.msgbox_output(self, info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
self.finish_operation()
|
||||
|
||||
def __update_config__(self):
|
||||
|
||||
Config["Filter"]["BandPassLow"] = self.ui.doubleSpinBox_bandPassLow.value()
|
||||
Config["Filter"]["BandPassHigh"] = self.ui.doubleSpinBox_bandPassHigh.value()
|
||||
Config["PeaksValue"] = self.ui.spinBox_peaksValue.value()
|
||||
Config["AmpValue"] = self.ui.doubleSpinBox_ampValue.value()
|
||||
Config["IntervalLow"] = self.ui.spinBox_intervalLow.value()
|
||||
Config["IntervalHigh"] = self.ui.spinBox_intervalHigh.value()
|
||||
Config["UseCPU"] = self.ui.checkBox_useCPU.isChecked()
|
||||
Config["DetectMethod"] = self.ui.comboBox_model.currentText()
|
||||
|
||||
def update_ui_comboBox_model(self, model_list):
|
||||
|
||||
self.ui.comboBox_model.clear()
|
||||
self.ui.comboBox_model.addItems(model_list)
|
||||
|
||||
def finish_operation(self):
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.OPERATION_FINISHED))
|
||||
self.progressbar.setValue(100)
|
||||
QApplication.processEvents()
|
||||
|
||||
self.__enableAllButton__()
|
||||
|
||||
def add_progressbar(self):
|
||||
|
||||
self.progressbar = QProgressBar()
|
||||
self.progressbar.setRange(0, 100)
|
||||
self.progressbar.setValue(0)
|
||||
self.progressbar.setStyleSheet(Constants.PROGRESSBAR_STYLE)
|
||||
self.ui.statusBar.addPermanentWidget(self.progressbar)
|
||||
|
||||
def statusbar_show_msg(self, msg):
|
||||
|
||||
self.ui.statusBar.showMessage(msg)
|
||||
|
||||
def statusbar_clear_msg(self):
|
||||
|
||||
self.ui.statusBar.clearMessage()
|
||||
|
||||
|
||||
class Data:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.file_path_input = Config["Path"]["Input"]
|
||||
self.file_path_save = Config["Path"]["Save"]
|
||||
|
||||
self.data = None
|
||||
self.processed_data = None
|
||||
self.peak = None
|
||||
self.interval = None
|
||||
|
||||
def open_file(self):
|
||||
|
||||
if not Path(Config["Path"]["Input"]).exists():
|
||||
return False, Constants.INPUT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Data_Path_Not_Exist"]
|
||||
|
||||
try:
|
||||
self.data = read_csv(self.file_path_input,
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
except Exception:
|
||||
return False, Constants.INPUT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Read_File_Exception"]
|
||||
|
||||
return True, Constants.INPUT_FINISHED
|
||||
|
||||
def preprocess(self):
|
||||
|
||||
if self.data is None:
|
||||
return False, Constants.DETECT_JPEAK_PROCESS_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Raw_Data_Not_Exist"]
|
||||
|
||||
try:
|
||||
self.processed_data = preprocess(self.data,
|
||||
Config["InputConfig"]["Freq"],
|
||||
Config["Filter"]["BandPassLow"],
|
||||
Config["Filter"]["BandPassHigh"],
|
||||
Config["AmpValue"])
|
||||
except Exception:
|
||||
return False, Constants.DETECT_JPEAK_PROCESS_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Filter_Exception"]
|
||||
|
||||
return True, Constants.DETECT_JPEAK_PROCESS_FINISHED
|
||||
|
||||
def predict_Jpeak(self, model):
|
||||
|
||||
if not (Path(model.model_folder_path) / Path(model.selected_model)).exists():
|
||||
return False, Constants.DETECT_JPEAK_PREDICT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Model_File_Not_Exist"]
|
||||
|
||||
if self.processed_data is None:
|
||||
return False, Constants.DETECT_JPEAK_PREDICT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Processed_Data_Not_Exist"]
|
||||
|
||||
try:
|
||||
self.peak, self.interval = Jpeak_Detection(model.selected_model,
|
||||
Path(model.model_folder_path) / Path(model.selected_model),
|
||||
self.processed_data,
|
||||
Config["InputConfig"]["Freq"],
|
||||
Config["IntervalHigh"],
|
||||
Config["IntervalLow"],
|
||||
Config["PeaksValue"],
|
||||
Config["UseCPU"])
|
||||
except Exception:
|
||||
return False, Constants.DETECT_JPEAK_PREDICT_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Predict_Exception"]
|
||||
|
||||
return True, Constants.DETECT_JPEAK_PREDICT_FINISHED
|
||||
|
||||
def save(self, chunk):
|
||||
|
||||
if self.peak is None:
|
||||
return False, Constants.SAVING_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Peak_Not_Exist"]
|
||||
|
||||
try:
|
||||
# DataFrame(self.processed_data.reshape(-1)).to_csv(self.file_path_save,
|
||||
# index=False,
|
||||
# header=False,
|
||||
# float_format='%.4f')
|
||||
chunk.to_csv(self.file_path_save, mode='a', index=False, header=False)
|
||||
except Exception:
|
||||
return False, Constants.SAVING_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Save_Exception"]
|
||||
|
||||
return True, Constants.SAVING_FINISHED
|
||||
|
||||
|
||||
class Model:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.model_folder_path = Config["ModelFolderPath"]
|
||||
self.model_list = None
|
||||
self.selected_model_path = None
|
||||
self.selected_model = None
|
||||
|
||||
def seek_model(self):
|
||||
|
||||
if not Path(Config["ModelFolderPath"]).exists():
|
||||
return False, Constants.LOAD_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Model_Path_Not_Exist"]
|
||||
|
||||
try:
|
||||
self.model_list = [file.name for file in Path(Config["ModelFolderPath"]).iterdir() if file.is_file()]
|
||||
if len(self.model_list) == 0:
|
||||
return False, Constants.DETECT_JPEAK_FAILURE_REASON["Model_File_Not_Exist"]
|
||||
except Exception:
|
||||
return False, Constants.LOAD_FAILURE + Constants.DETECT_JPEAK_FAILURE_REASON["Read_Model_Exception"]
|
||||
|
||||
return True, Constants.LOAD_FINISHED
|
||||
108
func/Module_mainwindow.py
Normal file
108
func/Module_mainwindow.py
Normal file
@ -0,0 +1,108 @@
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6.QtWidgets import QMainWindow, QMessageBox, QFileDialog
|
||||
from matplotlib import use
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from ui.MainWindow.MainWindow_menu import Ui_Signal_Label
|
||||
|
||||
from func.Module_preprocess import MainWindow_preprocess
|
||||
from func.Module_detect_Jpeak import MainWindow_detect_Jpeak
|
||||
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
|
||||
|
||||
use("QtAgg")
|
||||
|
||||
|
||||
Config = {
|
||||
|
||||
}
|
||||
|
||||
|
||||
class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
super(MainWindow, self).__init__()
|
||||
self.ui = Ui_Signal_Label()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
self.__read_config__()
|
||||
self.ui.plainTextEdit_root_path.setPlainText(Config["Path"]["Root"])
|
||||
self.seek_sampID(Path(Config["Path"]["Root"]) / Path(ConfigParams.PUBLIC_PATH_ORGBCG_TEXT))
|
||||
|
||||
self.preprocess = None
|
||||
|
||||
# 消息弹窗初始化
|
||||
self.msgBox = QMessageBox()
|
||||
self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE)
|
||||
|
||||
# 绑定槽函数
|
||||
self.ui.pushButton_open.clicked.connect(self.__slot_btn_open__)
|
||||
self.ui.pushButton_preprocess_BCG.clicked.connect(self.__slot_btn_preprocess__)
|
||||
self.ui.pushButton_preprocess_ECG.clicked.connect(self.__slot_btn_preprocess__)
|
||||
self.ui.pushButton_detect_Jpeak.clicked.connect(self.__slot_btn_detect_Jpeak__)
|
||||
|
||||
@staticmethod
|
||||
def __read_config__():
|
||||
|
||||
if not Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.PUBLIC_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.PUBLIC_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.PUBLIC_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
|
||||
@staticmethod
|
||||
def __write_config__():
|
||||
|
||||
with open(Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH), "w") as f:
|
||||
dump(Config, f)
|
||||
|
||||
def __slot_btn_open__(self):
|
||||
|
||||
file_dialog = QFileDialog()
|
||||
file_dialog.setFileMode(QFileDialog.Directory)
|
||||
file_dialog.setOption(QFileDialog.ShowDirsOnly, True)
|
||||
if file_dialog.exec_() == QFileDialog.Accepted:
|
||||
self.seek_sampID(Path(file_dialog.selectedFiles()[0]) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT)
|
||||
self.ui.plainTextEdit_root_path.setPlainText(file_dialog.selectedFiles()[0])
|
||||
|
||||
# 修改配置
|
||||
Config["Path"]["Root"] = str(file_dialog.selectedFiles()[0])
|
||||
self.__write_config__()
|
||||
else:
|
||||
PublicFunc.msgbox_output(self, Constants.OPERATION_CANCELED, Constants.MSGBOX_TYPE_INFO)
|
||||
|
||||
def __slot_btn_preprocess__(self):
|
||||
|
||||
self.preprocess = MainWindow_preprocess()
|
||||
|
||||
sender = self.sender()
|
||||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||||
sampID = int(self.ui.comboBox_sampID.currentText())
|
||||
if sender == self.ui.pushButton_preprocess_BCG:
|
||||
mode = "BCG"
|
||||
self.preprocess.show(mode, root_path, sampID)
|
||||
elif sender == self.ui.pushButton_preprocess_ECG:
|
||||
mode = "ECG"
|
||||
self.preprocess.show(mode, root_path, sampID)
|
||||
|
||||
def __slot_btn_detect_Jpeak__(self):
|
||||
|
||||
self.detect_Jpeak = MainWindow_detect_Jpeak()
|
||||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||||
sampID = int(self.ui.comboBox_sampID.currentText())
|
||||
self.detect_Jpeak.show(root_path, sampID)
|
||||
|
||||
def seek_sampID(self, path):
|
||||
|
||||
if not Path(path).exists():
|
||||
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_ROOT_PATH_NOT_EXIST, Constants.MSGBOX_TYPE_ERROR)
|
||||
return
|
||||
|
||||
sub_folders = [item.name for item in Path(path).iterdir() if item.is_dir()]
|
||||
self.ui.comboBox_sampID.addItems(sub_folders)
|
||||
525
func/Module_preprocess.py
Normal file
525
func/Module_preprocess.py
Normal file
@ -0,0 +1,525 @@
|
||||
from gc import collect
|
||||
from pathlib import Path
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from PySide6.QtWidgets import QMessageBox, QMainWindow, QWidget, QPushButton, QProgressBar, QApplication
|
||||
from matplotlib import gridspec
|
||||
from matplotlib.backends.backend_qt import NavigationToolbar2QT
|
||||
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
|
||||
from overrides import overrides
|
||||
from pandas import read_csv, DataFrame
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
from func.utils.Constants import Constants, ConfigParams
|
||||
from func.Filters.Preprocessing import Butterworth_for_BCG_PreProcess, Butterworth_for_ECG_PreProcess
|
||||
|
||||
from ui.MainWindow.MainWindow_preprocess import Ui_MainWindow_preprocess
|
||||
from ui.setting.preprocess_input_setting import Ui_MainWindow_preprocess_input_setting
|
||||
|
||||
|
||||
Config = {
|
||||
|
||||
}
|
||||
|
||||
ButtonState = {
|
||||
"Default": {
|
||||
"pushButton_input_setting": True,
|
||||
"pushButton_input": True,
|
||||
"pushButton_view": False,
|
||||
"pushButton_save": False
|
||||
},
|
||||
"Current": {
|
||||
"pushButton_input_setting": True,
|
||||
"pushButton_input": True,
|
||||
"pushButton_view": False,
|
||||
"pushButton_save": False
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SettingWindow(QMainWindow):
|
||||
|
||||
def __init__(self, mode, root_path, sampID):
|
||||
|
||||
super(SettingWindow, self).__init__()
|
||||
self.ui = Ui_MainWindow_preprocess_input_setting()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
self.mode = mode
|
||||
self.root_path = root_path
|
||||
self.sampID = sampID
|
||||
|
||||
self.config = None
|
||||
self.__read_config__()
|
||||
|
||||
self.ui.spinBox_input_freq.valueChanged.connect(self.__update_ui__)
|
||||
self.ui.pushButton_confirm.clicked.connect(self.__write_config__)
|
||||
self.ui.pushButton_cancel.clicked.connect(self.__rollback_config__)
|
||||
self.ui.pushButton_cancel.clicked.connect(self.close)
|
||||
|
||||
def __read_config__(self):
|
||||
|
||||
if not Path(ConfigParams.PREPROCESS_CONFIG_FILE_PATH).exists():
|
||||
with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.PREPROCESS_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "r") as f:
|
||||
file_config = load(f.read(), Loader=FullLoader)
|
||||
Config.update(file_config)
|
||||
self.config = file_config
|
||||
|
||||
if self.mode == "BCG":
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) / Path(ConfigParams.PREPROCESS_INPUT_BCG_FILENAME +
|
||||
str(Config["InputConfig"]["Freq"]) +
|
||||
ConfigParams.ENDSWITH_TXT))),
|
||||
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) / Path(ConfigParams.PREPROCESS_SAVE_BCG_FILENAME +
|
||||
str(Config["InputConfig"]["Freq"]) +
|
||||
ConfigParams.ENDSWITH_TXT)))
|
||||
},
|
||||
"Mode": self.mode
|
||||
})
|
||||
else:
|
||||
Config.update({
|
||||
"Path": {
|
||||
"Input": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) / Path(ConfigParams.PREPROCESS_INPUT_ECG_FILENAME +
|
||||
str(Config["InputConfig"]["Freq"]) +
|
||||
ConfigParams.ENDSWITH_TXT))),
|
||||
"Save": str((Path(self.root_path) / ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) / Path(ConfigParams.PREPROCESS_SAVE_ECG_FILENAME +
|
||||
str(Config["InputConfig"]["Freq"]) +
|
||||
ConfigParams.ENDSWITH_TXT)))
|
||||
},
|
||||
"Mode": self.mode
|
||||
})
|
||||
|
||||
# 数据回显
|
||||
self.ui.spinBox_input_freq.setValue(Config["InputConfig"]["Freq"])
|
||||
self.ui.plainTextEdit_file_path_input.setPlainText(Config["Path"]["Input"])
|
||||
self.ui.plainTextEdit_file_path_save.setPlainText(Config["Path"]["Save"])
|
||||
|
||||
def __write_config__(self):
|
||||
|
||||
# 从界面写入配置
|
||||
Config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
|
||||
Config["Path"]["Input"] = self.ui.plainTextEdit_file_path_input.toPlainText()
|
||||
Config["Path"]["Save"] = self.ui.plainTextEdit_file_path_save.toPlainText()
|
||||
|
||||
# 保存配置到文件
|
||||
self.config["InputConfig"]["Freq"] = self.ui.spinBox_input_freq.value()
|
||||
|
||||
with open(ConfigParams.PREPROCESS_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(self.config, f)
|
||||
|
||||
self.close()
|
||||
|
||||
def __rollback_config__(self):
|
||||
|
||||
self.__read_config__()
|
||||
|
||||
def __update_ui__(self):
|
||||
|
||||
if self.mode == "BCG":
|
||||
self.ui.plainTextEdit_file_path_input.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.PREPROCESS_INPUT_BCG_FILENAME +
|
||||
str(self.ui.spinBox_input_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_ORGBCG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.PREPROCESS_SAVE_BCG_FILENAME +
|
||||
str(self.ui.spinBox_input_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
else:
|
||||
self.ui.plainTextEdit_file_path_input.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.PREPROCESS_INPUT_ECG_FILENAME +
|
||||
str(self.ui.spinBox_input_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
self.ui.plainTextEdit_file_path_save.setPlainText(
|
||||
str((Path(self.root_path) /
|
||||
ConfigParams.PUBLIC_PATH_PSG_TEXT /
|
||||
Path(str(self.sampID)) /
|
||||
Path(ConfigParams.PREPROCESS_SAVE_ECG_FILENAME +
|
||||
str(self.ui.spinBox_input_freq.value()) +
|
||||
ConfigParams.ENDSWITH_TXT))))
|
||||
|
||||
|
||||
class MainWindow_preprocess(QMainWindow):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
super(MainWindow_preprocess, self).__init__()
|
||||
self.ui = Ui_MainWindow_preprocess()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
self.mode = None
|
||||
self.root_path = None
|
||||
self.sampID = None
|
||||
|
||||
self.data = None
|
||||
|
||||
self.setting = None
|
||||
|
||||
# 初始化进度条
|
||||
self.progressbar = None
|
||||
self.add_progressbar()
|
||||
|
||||
#初始化画框
|
||||
self.fig = None
|
||||
self.canvas = None
|
||||
self.figToolbar = None
|
||||
self.gs = None
|
||||
self.ax0 = None
|
||||
|
||||
self.line_raw_data = None
|
||||
self.line_processed_data = None
|
||||
|
||||
self.msgBox = QMessageBox()
|
||||
self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE)
|
||||
|
||||
@overrides
|
||||
def show(self, mode, root_path, sampID):
|
||||
|
||||
super().show()
|
||||
self.mode = mode
|
||||
self.root_path = root_path
|
||||
self.sampID = sampID
|
||||
|
||||
self.setting = SettingWindow(mode, root_path, sampID)
|
||||
|
||||
# 初始化画框
|
||||
self.fig = plt.figure(figsize=(12, 9), dpi=100)
|
||||
self.canvas = FigureCanvasQTAgg(self.fig)
|
||||
self.figToolbar = NavigationToolbar2QT(self.canvas)
|
||||
for action in self.figToolbar.actions():
|
||||
if action.text() == "Subplots" or action.text() == "Customize":
|
||||
self.figToolbar.removeAction(action)
|
||||
self.ui.verticalLayout_canvas.addWidget(self.canvas)
|
||||
self.ui.verticalLayout_canvas.addWidget(self.figToolbar)
|
||||
self.gs = gridspec.GridSpec(1, 1, height_ratios=[1])
|
||||
self.fig.subplots_adjust(top=0.98, bottom=0.05, right=0.98, left=0.1, hspace=0, wspace=0)
|
||||
self.ax0 = self.fig.add_subplot(self.gs[0])
|
||||
self.ax0.grid(True)
|
||||
self.ax0.xaxis.set_major_formatter(ConfigParams.FORMATTER)
|
||||
|
||||
self.__resetAllButton__()
|
||||
|
||||
self.ui.label_mode.setText(self.mode)
|
||||
if self.mode == "BCG":
|
||||
self.ui.spinBox_bandPassOrder.setValue(Config["Filter"]["BCGBandPassOrder"])
|
||||
self.ui.doubleSpinBox_bandPassLow.setValue(Config["Filter"]["BCGBandPassLow"])
|
||||
self.ui.doubleSpinBox_bandPassHigh.setValue(Config["Filter"]["BCGBandPassHigh"])
|
||||
else:
|
||||
self.ui.spinBox_bandPassOrder.setValue(Config["Filter"]["ECGBandPassOrder"])
|
||||
self.ui.doubleSpinBox_bandPassLow.setValue(Config["Filter"]["ECGBandPassLow"])
|
||||
self.ui.doubleSpinBox_bandPassHigh.setValue(Config["Filter"]["ECGBandPassHigh"])
|
||||
|
||||
self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__)
|
||||
self.ui.pushButton_input_setting.clicked.connect(self.setting.show)
|
||||
self.ui.pushButton_view.clicked.connect(self.__slot_btn_view__)
|
||||
self.ui.pushButton_save.clicked.connect(self.__slot_btn_save__)
|
||||
self.ui.spinBox_bandPassOrder.editingFinished.connect(self.__update_config__)
|
||||
self.ui.doubleSpinBox_bandPassLow.editingFinished.connect(self.__update_config__)
|
||||
self.ui.doubleSpinBox_bandPassHigh.editingFinished.connect(self.__update_config__)
|
||||
|
||||
@overrides
|
||||
def closeEvent(self, event):
|
||||
|
||||
self.__disableAllButton__()
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.SHUTTING_DOWN))
|
||||
QApplication.processEvents()
|
||||
|
||||
# 清空画框
|
||||
if self.line_raw_data and self.line_processed_data:
|
||||
del self.line_raw_data
|
||||
del self.line_processed_data
|
||||
self.canvas.draw()
|
||||
|
||||
# 释放资源
|
||||
del self.data
|
||||
self.fig.clf()
|
||||
plt.close(self.fig)
|
||||
self.deleteLater()
|
||||
collect()
|
||||
self.canvas = None
|
||||
event.accept()
|
||||
|
||||
@staticmethod
|
||||
def __reset__():
|
||||
|
||||
ButtonState["Current"].update(ButtonState["Default"].copy())
|
||||
ButtonState["Current"]["pushButton_view"] = True
|
||||
|
||||
def __plot__(self):
|
||||
|
||||
# 清空画框
|
||||
if self.line_raw_data and self.line_processed_data:
|
||||
try:
|
||||
self.line_raw_data.remove()
|
||||
self.line_processed_data.remove()
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
sender = self.sender()
|
||||
|
||||
if sender == self.ui.pushButton_view:
|
||||
self.line_raw_data, = self.ax0.plot(self.data.raw_data,
|
||||
color=Constants.PLOT_COLOR_RED,
|
||||
label=Constants.PREPROCESS_PLOT_LABEL_ORIGINAL_DATA)
|
||||
self.line_processed_data, = self.ax0.plot(self.data.processed_data + Constants.PREPROCESS_OUTPUT_INPUT_AMP_OFFSET,
|
||||
color=Constants.PLOT_COLOR_BLUE,
|
||||
label=Constants.PREPROCESS_PLOT_LABEL_PROCESSED_DATA)
|
||||
self.ax0.legend(loc=Constants.PLOT_UPPER_RIGHT)
|
||||
status = True
|
||||
info = Constants.DRAWING_FINISHED
|
||||
else:
|
||||
status = False
|
||||
info = Constants.DRAWING_FAILURE
|
||||
|
||||
self.canvas.draw()
|
||||
return status, info
|
||||
|
||||
def __disableAllButton__(self):
|
||||
# 禁用所有按钮
|
||||
all_widgets = self.centralWidget().findChildren(QWidget)
|
||||
|
||||
# 迭代所有部件,查找按钮并禁用它们
|
||||
for widget in all_widgets:
|
||||
if isinstance(widget, QPushButton):
|
||||
if widget.objectName() in ButtonState["Current"].keys():
|
||||
widget.setEnabled(False)
|
||||
|
||||
def __enableAllButton__(self):
|
||||
# 启用按钮
|
||||
all_widgets = self.centralWidget().findChildren(QWidget)
|
||||
|
||||
# 迭代所有部件,查找按钮并启用它们
|
||||
for widget in all_widgets:
|
||||
if isinstance(widget, QPushButton):
|
||||
if widget.objectName() in ButtonState["Current"].keys():
|
||||
widget.setEnabled(ButtonState["Current"][widget.objectName()])
|
||||
|
||||
def __resetAllButton__(self):
|
||||
# 启用按钮
|
||||
all_widgets = self.centralWidget().findChildren(QWidget)
|
||||
|
||||
# 迭代所有部件,查找按钮并启用它们
|
||||
for widget in all_widgets:
|
||||
if isinstance(widget, QPushButton):
|
||||
if widget.objectName() in ButtonState["Default"].keys():
|
||||
widget.setEnabled(ButtonState["Default"][widget.objectName()])
|
||||
|
||||
def __slot_btn_input__(self):
|
||||
|
||||
self.__disableAllButton__()
|
||||
|
||||
# 清空画框
|
||||
if self.line_raw_data and self.line_processed_data:
|
||||
try:
|
||||
self.line_raw_data.remove()
|
||||
self.line_processed_data.remove()
|
||||
except ValueError:
|
||||
pass
|
||||
self.canvas.draw()
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.INPUTTING_DATA))
|
||||
self.progressbar.setValue(0)
|
||||
QApplication.processEvents()
|
||||
|
||||
# 导入数据
|
||||
self.data = Data()
|
||||
status, info = self.data.open_file()
|
||||
if not status:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
|
||||
self.finish_operation()
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
MainWindow_preprocess.__reset__()
|
||||
self.finish_operation()
|
||||
|
||||
def __slot_btn_view__(self):
|
||||
|
||||
self.__disableAllButton__()
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.PREPROCESS_PROCESSING_DATA))
|
||||
self.progressbar.setValue(0)
|
||||
QApplication.processEvents()
|
||||
|
||||
# 数据预处理
|
||||
status, info = self.data.preprocess()
|
||||
if not status:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
|
||||
self.finish_operation()
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.DRAWING_DATA))
|
||||
self.progressbar.setValue(50)
|
||||
QApplication.processEvents()
|
||||
|
||||
# 绘图
|
||||
status, info = self.__plot__()
|
||||
if not status:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
|
||||
self.finish_operation()
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
ButtonState["Current"]["pushButton_save"] = True
|
||||
self.finish_operation()
|
||||
|
||||
def __slot_btn_save__(self):
|
||||
|
||||
reply = QMessageBox.question(self, Constants.QUESTION_TITLE,
|
||||
Constants.QUESTION_CONTENT + Config["Path"]["Save"],
|
||||
QMessageBox.Yes | QMessageBox.No,
|
||||
QMessageBox.Yes)
|
||||
if reply == QMessageBox.Yes:
|
||||
self.__disableAllButton__()
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.SAVING_DATA))
|
||||
self.progressbar.setValue(0)
|
||||
QApplication.processEvents()
|
||||
|
||||
# 保存
|
||||
# status, info = self.data.save()
|
||||
total_rows = len(DataFrame(self.data.processed_data.reshape(-1)))
|
||||
chunk_size = ConfigParams.PREPROCESS_SAVE_CHUNK_SIZE
|
||||
with open(Config["Path"]["Save"], 'w') as f:
|
||||
for start in range(0, total_rows, chunk_size):
|
||||
end = min(start + chunk_size, total_rows)
|
||||
chunk = DataFrame(self.data.processed_data.reshape(-1)).iloc[start:end]
|
||||
status, info = self.data.save(chunk)
|
||||
progress = int((end / total_rows) * 100)
|
||||
self.progressbar.setValue(progress)
|
||||
QApplication.processEvents()
|
||||
|
||||
if not status:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
|
||||
PublicFunc.msgbox_output(self, info, Constants.MSGBOX_TYPE_ERROR)
|
||||
self.finish_operation()
|
||||
return
|
||||
else:
|
||||
PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
|
||||
PublicFunc.msgbox_output(self, info, Constants.TIPS_TYPE_INFO)
|
||||
|
||||
self.finish_operation()
|
||||
|
||||
def __update_config__(self):
|
||||
|
||||
if self.mode == "BCG":
|
||||
Config["Filter"]["BCGBandPassOrder"] = self.ui.spinBox_bandPassOrder.value()
|
||||
Config["Filter"]["BCGBandPassLow"] = self.ui.doubleSpinBox_bandPassLow.value()
|
||||
Config["Filter"]["BCGBandPassHigh"] = self.ui.doubleSpinBox_bandPassHigh.value()
|
||||
else:
|
||||
Config["Filter"]["ECGBandPassOrder"] = self.ui.spinBox_bandPassOrder.value()
|
||||
Config["Filter"]["ECGBandPassLow"] = self.ui.doubleSpinBox_bandPassLow.value()
|
||||
Config["Filter"]["ECGBandPassHigh"] = self.ui.doubleSpinBox_bandPassHigh.value()
|
||||
|
||||
def finish_operation(self):
|
||||
|
||||
self.statusbar_show_msg(PublicFunc.format_status_msg(Constants.OPERATION_FINISHED))
|
||||
self.progressbar.setValue(100)
|
||||
QApplication.processEvents()
|
||||
|
||||
self.__enableAllButton__()
|
||||
|
||||
def add_progressbar(self):
|
||||
|
||||
self.progressbar = QProgressBar()
|
||||
self.progressbar.setRange(0, 100)
|
||||
self.progressbar.setValue(0)
|
||||
self.progressbar.setStyleSheet(Constants.PROGRESSBAR_STYLE)
|
||||
self.ui.statusBar.addPermanentWidget(self.progressbar)
|
||||
|
||||
def statusbar_show_msg(self, msg):
|
||||
|
||||
self.ui.statusBar.showMessage(msg)
|
||||
|
||||
def statusbar_clear_msg(self):
|
||||
|
||||
self.ui.statusBar.clearMessage()
|
||||
|
||||
|
||||
class Data:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.file_path_input = Config["Path"]["Input"]
|
||||
self.file_path_save = Config["Path"]["Save"]
|
||||
|
||||
self.raw_data = None
|
||||
self.processed_data = None
|
||||
|
||||
def open_file(self):
|
||||
|
||||
if not Path(Config["Path"]["Input"]).exists():
|
||||
return False, Constants.INPUT_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Data_Path_Not_Exist"]
|
||||
|
||||
try:
|
||||
self.raw_data = read_csv(self.file_path_input,
|
||||
encoding=ConfigParams.UTF8_ENCODING,
|
||||
header=None).to_numpy().reshape(-1)
|
||||
except Exception:
|
||||
return False, Constants.INPUT_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Read_Data_Exception"]
|
||||
|
||||
return True, Constants.INPUT_FINISHED
|
||||
|
||||
def preprocess(self):
|
||||
|
||||
if self.raw_data is None:
|
||||
return False, Constants.PREPROCESS_PROCESS_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Raw_Data_Not_Exist"]
|
||||
|
||||
try:
|
||||
if Config["Mode"] == "BCG":
|
||||
self.processed_data = Butterworth_for_BCG_PreProcess(self.raw_data, type='bandpass',
|
||||
low_cut=Config["Filter"]["BCGBandPassLow"],
|
||||
high_cut=Config["Filter"]["BCGBandPassHigh"],
|
||||
order=Config["Filter"]["BCGBandPassOrder"],
|
||||
sample_rate=Config["InputConfig"]["Freq"])
|
||||
else:
|
||||
self.processed_data = Butterworth_for_ECG_PreProcess(self.raw_data, type='bandpass',
|
||||
low_cut=Config["Filter"]["ECGBandPassLow"],
|
||||
high_cut=Config["Filter"]["ECGBandPassHigh"],
|
||||
order=Config["Filter"]["ECGBandPassOrder"],
|
||||
sample_rate=Config["InputConfig"]["Freq"])
|
||||
except Exception:
|
||||
return False, Constants.PREPROCESS_PROCESS_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Filter_Exception"]
|
||||
|
||||
return True, Constants.PREPROCESS_PROCESS_FINISHED
|
||||
|
||||
def save(self, chunk):
|
||||
|
||||
if self.processed_data is None:
|
||||
return False, Constants.SAVING_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Processed_Data_Not_Exist"]
|
||||
|
||||
try:
|
||||
# DataFrame(self.processed_data.reshape(-1)).to_csv(self.file_path_save,
|
||||
# index=False,
|
||||
# header=False,
|
||||
# float_format='%.4f')
|
||||
chunk.to_csv(self.file_path_save, mode='a', index=False, header=False, float_format='%.4f')
|
||||
except Exception:
|
||||
return False, Constants.SAVING_FAILURE + Constants.PREPROCESS_FAILURE_REASON["Save_Exception"]
|
||||
|
||||
return True, Constants.SAVING_FINISHED
|
||||
270
func/utils/ConfigParams.py
Normal file
270
func/utils/ConfigParams.py
Normal file
@ -0,0 +1,270 @@
|
||||
from PySide6.QtGui import QIntValidator, QDoubleValidator
|
||||
from matplotlib.ticker import FuncFormatter
|
||||
|
||||
|
||||
class ConfigParams:
|
||||
|
||||
|
||||
# 公共
|
||||
PUBLIC_CONFIG_FILE_PATH: str = "./config/Config_public.yaml"
|
||||
PUBLIC_PATH_ORGBCG_TEXT: str = "OrgBCG_Text"
|
||||
PUBLIC_PATH_PSG_TEXT: str = "PSG_Text"
|
||||
PUBLIC_PATH_ORGBCG_ALIGNED: str = "OrgBCG_Aligned"
|
||||
PUBLIC_PATH_PSG_ALIGNED: str = "PSG_Aligned"
|
||||
PUBLIC_PATH_LABEL: str = "Label"
|
||||
PUBLIC_CONFIG_NEW_CONTENT = {
|
||||
"Path": {
|
||||
"Root": ""
|
||||
}
|
||||
}
|
||||
UTF8_ENCODING: str = "utf-8"
|
||||
GBK_ENCODING: str = "gbk"
|
||||
ENDSWITH_TXT: str = ".txt"
|
||||
ENDSWITH_CSV: str = ".csv"
|
||||
ENDSWITH_EDF: str = ".edf"
|
||||
FORMATTER = FuncFormatter(lambda x, p: f"{x:.0f}")
|
||||
ACTION_PAN_SHORTCUT_KEY: str = "X"
|
||||
ACTION_ZOOM_SHORTCUT_KEY: str = "C"
|
||||
|
||||
# 数据粗同步
|
||||
|
||||
# 预处理
|
||||
PREPROCESS_CONFIG_FILE_PATH: str = "./config/Config_preprocess.yaml"
|
||||
PREPROCESS_CONFIG_NEW_CONTENT = {
|
||||
"InputConfig": {
|
||||
"Freq": 1000
|
||||
},
|
||||
"Filter": {
|
||||
"BCGBandPassOrder": 4,
|
||||
"BCGBandPassLow": 2,
|
||||
"BCGBandPassHigh": 10,
|
||||
"ECGBandPassOrder": 3,
|
||||
"ECGBandPassLow": 1,
|
||||
"ECGBandPassHigh": 25
|
||||
}
|
||||
}
|
||||
PREPROCESS_INPUT_BCG_FILENAME: str = "orgBcg_Raw_"
|
||||
PREPROCESS_INPUT_ECG_FILENAME: str = "ECG I_"
|
||||
PREPROCESS_SAVE_BCG_FILENAME: str = "DSbcg_sig_"
|
||||
PREPROCESS_SAVE_ECG_FILENAME: str = "ECG_filter_"
|
||||
PREPROCESS_SAVE_CHUNK_SIZE: int = 1000000
|
||||
|
||||
# BCG的J峰算法定位
|
||||
DETECT_JPEAK_CONFIG_FILE_PATH: str = "./config/Config_detect_Jpeak.yaml"
|
||||
DETECT_JPEAK_CONFIG_NEW_CONTENT = {
|
||||
"InputConfig": {
|
||||
"Freq": 1000
|
||||
},
|
||||
"Filter": {
|
||||
"BandPassLow": 2,
|
||||
"BandPassHigh": 10
|
||||
},
|
||||
"ModelFolderPath": "./func/detect_Jpeak_model",
|
||||
"PeaksValue": 100,
|
||||
"AmpValue": 5,
|
||||
"IntervalLow": 50,
|
||||
"IntervalHigh": 140,
|
||||
"UseCPU": False,
|
||||
"DetectMethod": ""
|
||||
}
|
||||
DETECT_JPEAK_INPUT_BCG_FILENAME: str = "DSbcg_sig_"
|
||||
DETECT_JPEAK_SAVE_FILENAME: str = "JPeak_revise"
|
||||
DETECT_JPEAK_SAVE_CHUNK_SIZE: int = 100
|
||||
|
||||
|
||||
|
||||
# TODO:弃用
|
||||
|
||||
# 通用
|
||||
|
||||
# 目前用到这个编码的地方:
|
||||
# <BCG的质量评估打标>里的保存和读取csv文件的地方(注意的是,读取原始数据时依然使用UTF-8)
|
||||
|
||||
|
||||
VALIDATOR_INTEGER = QIntValidator(-2**31, 2**31 - 1)
|
||||
VALIDATOR_DOUBLE = QDoubleValidator(-1e100, 1e100, 10)
|
||||
|
||||
|
||||
|
||||
FONT: str = "Microsoft YaHei UI"
|
||||
|
||||
|
||||
# 菜单界面
|
||||
MATPLOTLIB_PLOT_PRECISION_PARAM: int = 10000
|
||||
|
||||
|
||||
# 数据粗同步
|
||||
APPROXIMATELY_ALIGN_INPUT_ORGBCG_FILENAME: str = "orgBcg_Raw_"
|
||||
APPROXIMATELY_ALIGN_INPUT_PSG_FILENAME: str = "A"
|
||||
APPROXIMATELY_ALIGN_SAVE_FILENAME: str = "Approximately_Align_Info"
|
||||
|
||||
APPROXIMATELY_ALIGN_INPUT_ORGBCG_DEFAULT_FS: int = 1000
|
||||
APPROXIMATELY_ALIGN_INPUT_PSG_DEFAULT_FS: int = 100
|
||||
|
||||
APPROXIMATELY_ALIGN_THO_CUSTOM_CHANNEL_DEFAULT: int = 3
|
||||
APPROXIMATELY_ALIGN_ABD_CUSTOM_CHANNE_DEFAULT: int = 4
|
||||
APPROXIMATELY_ALIGN_BUTTERORDER_DEFAULT: int = 4
|
||||
APPROXIMATELY_ALIGN_BUTTERLOWPASSFREQ_CHANNE_DEFAULT: float = 0.01
|
||||
APPROXIMATELY_ALIGN_BUTTERHIGHPASSFREQ_DEFAULT: float = 0.70
|
||||
APPROXIMATELY_ALIGN_APPLYFREQ_DEFAULT: float = 5
|
||||
|
||||
|
||||
# 预处理
|
||||
# PREPROCESS_INPUT_BCG_FILENAME: str = "orgBcg_Raw_"
|
||||
# PREPROCESS_INPUT_ECG_FILENAME: str = "ECG I_"
|
||||
# PREPROCESS_SAVE_BCG_FILENAME: str = "DSbcg_sig_"
|
||||
# PREPROCESS_SAVE_ECG_FILENAME: str = "ECG_filter_"
|
||||
|
||||
# PREPROCESS_INPUT_BCG_DEFAULT_FS: int = 1000
|
||||
# PREPROCESS_INPUT_BCG_SAVE_DEFAULT_FS: int = 1000
|
||||
# PREPROCESS_INPUT_ECG_DEFAULT_FS: int = 1000
|
||||
# PREPROCESS_INPUT_ECG_SAVE_DEFAULT_FS: int = 1000
|
||||
#
|
||||
# PREPROCESS_BANDPASS_LOW_DEFAULT: int = 2
|
||||
# PREPROCESS_BANDPASS_HIGH_DEFAULT: int = 10
|
||||
# PREPROCESS_FILTER_ORDER_DEFAULT: int = 4
|
||||
#
|
||||
# PREPROCESS_FILTER_BCG: str = "bandpass"
|
||||
# PREPROCESS_FILTER_ECG: str = "bandpass"
|
||||
|
||||
|
||||
# ECG的R峰算法定位
|
||||
DETECT_R_PEAK_INPUT_ECG_FILENAME: str = "ECG_filter_"
|
||||
DETECT_R_PEAK_SAVE_RPEAK_FILENAME: str = "final_Rpeak"
|
||||
|
||||
DETECT_R_PEAK_INPUT_ECG_DEFAULT_FS: int = 1000
|
||||
|
||||
DETECT_R_PEAK_PEAKS_VALUE_DEFAULT: int = 200
|
||||
DETECT_R_PEAK_BANDPASS_LOW_DEFAULT: int = 2
|
||||
DETECT_R_PEAK_BANDPASS_HIGH_DEFAULT: int = 15
|
||||
|
||||
DETECT_R_PEAK_DETECT_METHOD_PT: str = "pt"
|
||||
DETECT_R_PEAK_DETECT_METHOD_TA: str = "ta"
|
||||
DETECT_R_PEAK_DETECT_METHOD_WT: str = "Wt"
|
||||
DETECT_R_PEAK_DETECT_METHOD_HAMILTON: str = "Hamilton"
|
||||
DETECT_R_PEAK_DETECT_METHOD_ENGZEE: str = "Engzee"
|
||||
|
||||
|
||||
# BCG的J峰算法定位
|
||||
DETECT_J_PEAK_INPUT_BCG_FILENAME: str = "DSbcg_sig_"
|
||||
DETECT_J_PEAK_SAVE_JPEAK_FILENAME: str = "JPeak_revise"
|
||||
|
||||
DETECT_J_PEAK_INPUT_BCG_DEFAULT_FS: int = 1000
|
||||
|
||||
DETECT_J_PEAK_BANDPASS_LOW_DEFAULT: int = 2
|
||||
DETECT_J_PEAK_BANDPASS_HIGH_DEFAULT: int = 10
|
||||
DETECT_J_PEAK_PEAKS_VALUE_DEFAULT: int = 100
|
||||
DETECT_J_PEAK_AMP_VALUE_DEFAULT: int = 5
|
||||
DETECT_J_PEAK_INTERVAL_LOW_DEFAULT: int = 50
|
||||
DETECT_J_PEAK_INTERVAL_HIGH_DEFAULT: int = 140
|
||||
|
||||
DETECT_J_PEAK_UNET_MODEL1_PKL_PATH: str = "./func/result/Fivelayer_Unet/1.pkl"
|
||||
DETECT_J_PEAK_UNET_MODEL2_PKL_PATH: str = "./func/result/Fivelayer_Unet/2.pkl"
|
||||
DETECT_J_PEAK_LSTMUNET_MODEL1_PKL_PATH: str = "./func/result/Fivelayer_Lstm_Unet/1.pkl"
|
||||
DETECT_J_PEAK_LSTMUNET_MODEL2_PKL_PATH: str = "./func/result/Fivelayer_Lstm_Unet/2.pkl"
|
||||
|
||||
DETECT_J_PEAK_UNET_MODEL1_NAME: str = "Fivelayer_Unet_1"
|
||||
DETECT_J_PEAK_UNET_MODEL2_NAME: str = "Fivelayer_Unet_2"
|
||||
DETECT_J_PEAK_LSTMUNET_MODEL1_NAME: str = "Fivelayer_Lstm_Unet_1"
|
||||
DETECT_J_PEAK_LSTMUNET_MODEL2_NAME: str = "Fivelayer_Lstm_Unet_2"
|
||||
|
||||
|
||||
# 人工纠正
|
||||
LABEL_CHECK_INPUT_BCG_FILENAME: str = "DSbcg_sig_"
|
||||
LABEL_CHECK_INPUT_JPEAK_FILENAME: str = "JPeak_revise"
|
||||
LABEL_CHECK_SAVE_JPEAK_FILENAME: str = "JPeak_revise_corrected"
|
||||
LABEL_CHECK_INPUT_ECG_FILENAME: str = "ECG_filter_"
|
||||
LABEL_CHECK_INPUT_RPEAK_FILENAME: str = "final_Rpeak"
|
||||
LABEL_CHECK_SAVE_RPEAK_FILENAME: str = "final_Rpeak_corrected"
|
||||
|
||||
LABEL_CHECK_INPUT_DEFAULT_FS: int = 1000
|
||||
|
||||
LABEL_CHECK_DATA1_FILTER_ORDER_DEFAULT: int = 2
|
||||
LABEL_CHECK_DATA1_BANDPASS_LOW_DEFAULT: int = 2
|
||||
LABEL_CHECK_DATA1_BANDPASS_HIGH_DEFAULT: int = 10
|
||||
LABEL_CHECK_DATA2_FILTER_ORDER_DEFAULT: int = 2
|
||||
LABEL_CHECK_DATA2_BANDPASS_LOW_DEFAULT: int = 2
|
||||
LABEL_CHECK_DATA2_BANDPASS_HIGH_DEFAULT: int = 15
|
||||
LABEL_CHECK_FINDPEAKS_MIN_INTERVAL_DEFAULT: int = 1000
|
||||
LABEL_CHECK_FINDPEAKS_MIN_HEIGHT_DEFAULT: int = 0.5
|
||||
LABEL_CHECK_MOVELENGTH_DEFAULT: int = 15000
|
||||
LABEL_CHECK_MAXRANGE_DEFAULT: int = 60000
|
||||
LABEL_CHECK_MOVESPEED_DEFAULT: int = 1000
|
||||
|
||||
LABEL_CHECK_FILTER: str = "bandpass"
|
||||
|
||||
LABEL_CHECK_LABEL_TRANSPARENCY: float = 0.2
|
||||
|
||||
LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY: str = "Z"
|
||||
|
||||
|
||||
# 体动打标
|
||||
ARTIFACT_LABEL_INPUT_BCG_FILENAME: str = "BCG_sync_"
|
||||
ARTIFACT_LABEL_INPUT_XINXIAO_FILENAME: str = "orgBcg_sync_"
|
||||
ARTIFACT_LABEL_SAVE_TXT_ARTIFACT_FILENAME: str = "Artifact_a"
|
||||
ARTIFACT_LABEL_SAVE_TXT_ARTIFACT_AMOUNT_FILENAME: str = "Artifact_b"
|
||||
ARTIFACT_LABEL_SAVE_CSV_ARTIFACT_FILENAME: str = "Artifact_c"
|
||||
|
||||
ARTIFACT_LABEL_INPUT_XINXIAO_DEFAULT_FS: int = 1000
|
||||
ARTIFACT_LABEL_INPUT_BCG_DEFAULT_FS: int = 1000
|
||||
|
||||
ARTIFACT_LABEL_MOVELENGTH_DEFAULT: int = 15000
|
||||
ARTIFACT_LABEL_MAXRANGE_DEFAULT: int = 60000
|
||||
ARTIFACT_LABEL_MOVESPEED_DEFAULT: int = 1000
|
||||
|
||||
ARTIFACT_LABEL_LABEL_TRANSPARENCY: float = 0.3
|
||||
|
||||
ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY: str = "Z"
|
||||
|
||||
|
||||
# 质量打标
|
||||
BCG_QUALITY_LABEL_INPUT_BCG_FILENAME: str = "BCG_sync_"
|
||||
BCG_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME: str = "Artifact_a"
|
||||
BCG_QUALITY_LABEL_SAVE_FILENAME: str = "SQ_label_"
|
||||
|
||||
BCG_QUALITY_LABEL_INPUT_DEFAULT_FS: int = 1000
|
||||
|
||||
BCG_QUALITY_LABEL_SAVE_MODE_10S: str = "10s"
|
||||
BCG_QUALITY_LABEL_SAVE_MODE_30S: str = "30s"
|
||||
|
||||
BCG_QUALITY_LABEL_MODE_10S_LENGTH = 10 * BCG_QUALITY_LABEL_INPUT_DEFAULT_FS
|
||||
BCG_QUALITY_LABEL_MODE_30S_LENGTH = 30 * BCG_QUALITY_LABEL_INPUT_DEFAULT_FS
|
||||
|
||||
|
||||
# 呼吸可用性及间期标注
|
||||
RESP_QUALITY_LABEL_INPUT_XINXIAO_FILENAME: str = "orgBcg_sync_"
|
||||
RESP_QUALITY_LABEL_INPUT_THO_FILENAME: str = "Effort_Tho_sync_"
|
||||
RESP_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME: str = "Artifact_a"
|
||||
RESP_QUALITY_LABEL_SAVE_RESP_QUALITY_LABNEL_FILENAME: str = "Resp_quality_label"
|
||||
RESP_QUALITY_LABEL_SAVE_THO_PEAK_FILENAME: str = "Tho_peak"
|
||||
|
||||
RESP_QUALITY_LABEL_INPUT_XINXIAO_DEFAULT_FS: int = 1000
|
||||
RESP_QUALITY_LABEL_INPUT_THO_DEFAULT_FS: int = 200
|
||||
|
||||
RESP_QUALITY_LABEL_PARTS_TIME_SEC: int = 30
|
||||
RESP_QUALITY_LABEL_PREPROCESS_FC: int = 1
|
||||
|
||||
RESP_QUALITY_LABEL_THRESHOLD1_DEFAULT: float = 0.65
|
||||
RESP_QUALITY_LABEL_THRESHOLD2_DEFAULT: float = 0.8
|
||||
RESP_QUALITY_LABEL_FINDPEAKS_MIN_INTERVAL_DEFAULT: int = 300
|
||||
RESP_QUALITY_LABEL_FINDPEAKS_MIN_HEIGHT_DEFAULT: float = 0.1
|
||||
RESP_QUALITY_LABEL_CUSTOM_LOW_DEFAULT: float = 0.1
|
||||
RESP_QUALITY_LABEL_CUSTOM_HIGH_DEFAULT: float = 1
|
||||
|
||||
RESP_QUALITY_LABEL_LABEL_TRANSPARENCY: float = 0.2
|
||||
|
||||
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY: str = "Z"
|
||||
|
||||
|
||||
# 睡眠呼吸暂停事件打标
|
||||
|
||||
|
||||
# 禁止实例化
|
||||
def __new__(cls):
|
||||
raise TypeError("Constants class cannot be instantiated")
|
||||
|
||||
|
||||
# 禁止修改常量
|
||||
@classmethod
|
||||
def __setattr__(cls, key, value):
|
||||
raise AttributeError("Cannot modify constants")
|
||||
411
func/utils/Constants.py
Normal file
411
func/utils/Constants.py
Normal file
@ -0,0 +1,411 @@
|
||||
from func.utils.ConfigParams import ConfigParams
|
||||
|
||||
|
||||
class Constants:
|
||||
|
||||
# 公共
|
||||
TIPS_TYPE_INFO: str = "Info"
|
||||
TIPS_TYPE_ERROR: str = "Error"
|
||||
MSGBOX_TYPE_INFO: str = "Info"
|
||||
MSGBOX_TYPE_WARNING: str = "Warning"
|
||||
MSGBOX_TYPE_ERROR: str = "Error"
|
||||
MSGBOX_TYPE_QUESTION: str = "Question"
|
||||
|
||||
INPUTTING_DATA: str = "正在导入数据"
|
||||
INPUT_FINISHED: str = "导入完成"
|
||||
INPUT_FAILURE: str = "导入失败"
|
||||
|
||||
LOADING_MODEL: str = "正在读取模型"
|
||||
LOAD_FINISHED: str = "读取完成"
|
||||
LOAD_FAILURE: str = "读取失败"
|
||||
|
||||
DRAWING_DATA: str = "正在绘制图形"
|
||||
DRAWING_FINISHED: str = "绘制完成"
|
||||
DRAWING_FAILURE: str = "绘制失败"
|
||||
|
||||
SAVING_DATA: str = "正在保存数据"
|
||||
SAVING_FINISHED: str = "保存完成"
|
||||
SAVING_FAILURE: str = "保存失败"
|
||||
|
||||
OPERATION_FINISHED: str = "操作完成"
|
||||
OPERATION_FAILURE: str = "操作失败"
|
||||
|
||||
UNKNOWN_ERROR: str = "未知错误"
|
||||
SHUTTING_DOWN: str = "正在关闭窗口"
|
||||
|
||||
QUESTION_TITLE: str = "警告:确认操作"
|
||||
QUESTION_CONTENT: str = "你确定要保存结果到"
|
||||
PLOT_UPPER_RIGHT: str = "upper right"
|
||||
STRING_IS_EMPTY: str = ""
|
||||
STRING_IS_NAN: str = "nan"
|
||||
|
||||
PLOT_COLOR_RED: str = "r"
|
||||
PLOT_COLOR_GREEN: str = "g"
|
||||
PLOT_COLOR_BLUE: str = "b"
|
||||
PLOT_COLOR_ORANGE: str = "orange"
|
||||
PLOT_COLOR_WHITE: str = "white"
|
||||
PLOT_COLOR_BLACK: str = "black"
|
||||
PLOT_COLOR_PINK: str = "#ff00ff"
|
||||
PLOT_COLOR_PURPLE: str = "m"
|
||||
PLOT_COLOR_GRAY: str = "gray"
|
||||
PLOT_COLOR_DEEP_YELLOW: str = "#ffa500"
|
||||
PLOT_COLOR_YELLOW: str = "#ffff00"
|
||||
PLOT_COLOR_AQUA: str = "#00ffff"
|
||||
PLOT_COLOR_PURPLE_PINK: str = "#ee82ee"
|
||||
PLOT_COLOR_DEEP_GREY: str = "#808080"
|
||||
|
||||
PROGRESSBAR_STYLE: str = """
|
||||
QProgressBar {
|
||||
border: 1px solid #020066;
|
||||
border-radius: 6px;
|
||||
font-size: 16px;
|
||||
color: black;
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
background: #E5E4E4;
|
||||
}
|
||||
QProgressBar::chunk {
|
||||
background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #9AFF99, stop:1 #9A9AFE);
|
||||
border-radius: 6px;
|
||||
}
|
||||
"""
|
||||
|
||||
# 预处理
|
||||
PREPROCESS_PROCESSING_DATA: str = "正在处理数据"
|
||||
PREPROCESS_PROCESS_FINISHED: str = "处理完成"
|
||||
PREPROCESS_PROCESS_FAILURE: str = "处理失败"
|
||||
|
||||
PREPROCESS_FAILURE_REASON = {
|
||||
"Data_Path_Not_Exist": "(路径不存在)",
|
||||
"Read_Data_Exception": "(读取数据异常)",
|
||||
"Raw_Data_Not_Exist": "(原始数据不存在)",
|
||||
"Filter_Exception": "(滤波器异常)",
|
||||
"Processed_Data_Not_Exist": "(处理后数据不存在)",
|
||||
"Save_Exception": "(保存异常)"
|
||||
}
|
||||
|
||||
PREPROCESS_PLOT_LABEL_ORIGINAL_DATA: str = "Original Data"
|
||||
PREPROCESS_PLOT_LABEL_PROCESSED_DATA: str = "Processed Data"
|
||||
PREPROCESS_OUTPUT_INPUT_AMP_OFFSET: int = 1850
|
||||
|
||||
# BCG的J峰算法定位
|
||||
DETECT_JPEAK_PROCESSING_DATA: str = "正在处理数据"
|
||||
DETECT_JPEAK_PROCESS_FINISHED: str = "处理完成"
|
||||
DETECT_JPEAK_PROCESS_FAILURE: str = "处理失败"
|
||||
|
||||
DETECT_JPEAK_PREDICTING_PEAK: str = "正在预测峰值"
|
||||
DETECT_JPEAK_PREDICT_FINISHED: str = "预测完成"
|
||||
DETECT_JPEAK_PREDICT_FAILURE: str = "预测失败"
|
||||
|
||||
DETECT_JPEAK_FAILURE_REASON = {
|
||||
"Data_Path_Not_Exist": "(数据路径不存在)",
|
||||
"Read_Data_Exception": "(读取数据异常)",
|
||||
"Model_Path_Not_Exist": "(模型路径不存在)",
|
||||
"Model_File_Not_Exist": "(模型文件不存在)",
|
||||
"Read_Model_Exception": "(读取模型异常)",
|
||||
"Predict_Exception": "(模型预测异常)",
|
||||
"Raw_Data_Not_Exist": "(原始数据不存在)",
|
||||
"Filter_Exception": "(滤波器异常)",
|
||||
"Processed_Data_Not_Exist": "(处理后数据不存在)",
|
||||
"Peak_Not_Exist": "(预测的峰值不存在)",
|
||||
"Save_Exception": "(保存异常)"
|
||||
}
|
||||
|
||||
DETECT_J_PEAK_DATA_LENGTH_POINTS: str = "数据长度(点数):"
|
||||
DETECT_J_PEAK_DURATION_MIN: str = "数据时长(分钟):"
|
||||
DETECT_J_PEAK_JPEAK_AMOUNT: str = "J峰个数:"
|
||||
DETECT_J_PEAK_PLOT_LABEL_BCG: str = "BCG_Processed"
|
||||
DETECT_J_PEAK_PLOT_LABEL_J_PEAKS: str = "J_Peaks"
|
||||
DETECT_J_PEAK_PLOT_LABEL_INTERVAL: str = "Interval"
|
||||
|
||||
# TODO:弃用
|
||||
|
||||
# 通用
|
||||
|
||||
FOLDER_DIR_NOT_EXIST_THEN_CREATE: str = "检测到保存路径所指向的文件夹不存在,已创建相应文件夹"
|
||||
|
||||
|
||||
# 菜单界面
|
||||
MAINWINDOW_ROOT_PATH_NOT_EXIST: str = "根目录路径输入错误"
|
||||
MAINWINDOW_MSGBOX_TITLE: str = "消息"
|
||||
MAINWINDOW_DIALOG_TITLE: str = "确认数据的采样率"
|
||||
MAINWINDOW_BACK_TO_MENU: str = "返回主菜单"
|
||||
MAINWINDOW_QUESTION_BACK_TO_MENU: str = "确定要返回主菜单吗"
|
||||
|
||||
|
||||
# 数据粗同步
|
||||
APPROXIMATELY_ALIGN_FILES_NOT_FOUND: str = f"无法找到{ConfigParams.APPROXIMATELY_ALIGN_INPUT_ORGBCG_FILENAME}{ConfigParams.ENDSWITH_TXT}或{ConfigParams.APPROXIMATELY_ALIGN_INPUT_PSG_FILENAME}{ConfigParams.ENDSWITH_EDF},无法执行<数据粗同步>"
|
||||
APPROXIMATELY_ALIGN_FILES_FOUND: str = f"找到{ConfigParams.APPROXIMATELY_ALIGN_INPUT_ORGBCG_FILENAME}{ConfigParams.ENDSWITH_TXT}和{ConfigParams.APPROXIMATELY_ALIGN_INPUT_PSG_FILENAME}{ConfigParams.ENDSWITH_EDF}"
|
||||
|
||||
APPROXIMATELY_ALIGN_RUNNING: str = "开始执行任务<数据粗同步>"
|
||||
APPROXIMATELY_RECORD_NOT_FOUND: str = "没有保存记录"
|
||||
|
||||
# ECG的R峰算法定位
|
||||
DETECT_R_PEAK_FILES_NOT_FOUND: str = f"无法找到{ConfigParams.DETECT_R_PEAK_INPUT_ECG_FILENAME}{ConfigParams.ENDSWITH_TXT},无法执行<R峰提取>"
|
||||
DETECT_R_PEAK_FILES_FOUND: str = f"找到{ConfigParams.DETECT_R_PEAK_INPUT_ECG_FILENAME}{ConfigParams.ENDSWITH_TXT}"
|
||||
|
||||
DETECT_R_PEAK_RUNNING: str = "开始执行任务<ECG的R峰算法定位>"
|
||||
DETECT_R_PEAK_PLOT_LABEL_RRIV: str = "RRIV"
|
||||
DETECT_R_PEAK_PLOT_LABEL_ECG: str = "ECG"
|
||||
DETECT_R_PEAK_PLOT_LABEL_R_PEAKS: str = "R_peaks"
|
||||
DETECT_R_PEAK_PLOT_LABEL_INTERVAL: str = "Interval"
|
||||
DETECT_R_PEAK_DATA_LENGTH_POINTS: str = "数据长度(点数):"
|
||||
DETECT_R_PEAK_DURATION_MIN: str = "数据时长(分钟):"
|
||||
DETECT_R_PEAK_RPEAK_AMOUNT: str = "R峰个数:"
|
||||
|
||||
|
||||
|
||||
# 人工纠正
|
||||
LABEL_CHECK_FILES_BCG_NOT_FOUND: str = f"无法找到{ConfigParams.LABEL_CHECK_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}或{ConfigParams.LABEL_CHECK_INPUT_JPEAK_FILENAME}{ConfigParams.ENDSWITH_TXT},无法执行<BCG的J峰人工纠正>"
|
||||
LABEL_CHECK_FILES_BCG_FOUND: str = f"找到{ConfigParams.LABEL_CHECK_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}和{ConfigParams.LABEL_CHECK_INPUT_JPEAK_FILENAME}{ConfigParams.ENDSWITH_TXT}"
|
||||
LABEL_CHECK_FILES_ECG_NOT_FOUND: str = f"无法找到{ConfigParams.LABEL_CHECK_INPUT_ECG_FILENAME}{ConfigParams.ENDSWITH_TXT}或{ConfigParams.LABEL_CHECK_INPUT_RPEAK_FILENAME}{ConfigParams.ENDSWITH_TXT},无法执行<ECG的R峰人工纠正>"
|
||||
LABEL_CHECK_FILES_ECG_FOUND: str = f"找到{ConfigParams.LABEL_CHECK_INPUT_ECG_FILENAME}{ConfigParams.ENDSWITH_TXT}和{ConfigParams.LABEL_CHECK_INPUT_RPEAK_FILENAME}{ConfigParams.ENDSWITH_TXT}"
|
||||
LABEL_CHECK_HISTORICAL_SAVE_FOUND: str = f"找到历史存档文件{ConfigParams.LABEL_CHECK_SAVE_JPEAK_FILENAME}{ConfigParams.ENDSWITH_TXT}或{ConfigParams.LABEL_CHECK_SAVE_RPEAK_FILENAME}{ConfigParams.ENDSWITH_TXT},已成功读取"
|
||||
|
||||
LABEL_CHECK_RUNNING: str = "开始执行任务<人工纠正>"
|
||||
LABEL_CHECK_BCG_MODE: str = "BCG_MODE"
|
||||
LABEL_CHECK_ECG_MODE: str = "ECG_MODE"
|
||||
LABEL_CHECK_PLOT_LABEL_DATA1: str = "Data 1"
|
||||
LABEL_CHECK_PLOT_LABEL_DATA2: str = "Data 2"
|
||||
LABEL_CHECK_PLOT_LABEL_LABEL1: str = "Label 1"
|
||||
LABEL_CHECK_PLOT_LABEL_LABEL2: str = "Label 2"
|
||||
LABEL_CHECK_PLOT_LABEL_VLINE: str = "vline"
|
||||
LABEL_CHECK_PLOT_LABEL_HLINE: str = "hline"
|
||||
LABEL_CHECK_AUTOPLAY_LEFT: str = "LEFT"
|
||||
LABEL_CHECK_AUTOPLAY_PAUSE: str = "PAUSE"
|
||||
LABEL_CHECK_AUTOPLAY_RIGHT: str = "RIGHT"
|
||||
LABEL_CHECK_AUTOPLAY_LEFT_INFO: str = "开始自动播放-向左"
|
||||
LABEL_CHECK_AUTOPLAY_PAUSE_INFO: str = "暂停自动播放"
|
||||
LABEL_CHECK_AUTOPLAY_RIGHT_INFO: str = "开始自动播放-向右"
|
||||
LABEL_CHECK_AUTOPLAY_PRESET1_INFO: str = "切换到自动播放-预设1"
|
||||
LABEL_CHECK_AUTOPLAY_PRESET2_INFO: str = "切换到自动播放-预设2"
|
||||
LABEL_CHECK_AUTOPLAY_PRESET3_INFO: str = "切换到自动播放-预设3"
|
||||
LABEL_CHECK_AUTOPLAY_PRESET_CUSTOM_INFO: str = "切换到自动播放-自定义"
|
||||
LABEL_CHECK_AUTOPLAY_PRESET_CUSTOM_WARNING: str = "自定义的输入参数未做任何检查,请斟酌输入参数,否则可能会导致程序异常"
|
||||
LABEL_CHECK_JUMP_X_INDEX: str = "跳转到x坐标: "
|
||||
LABEL_CHECK_RECOVER_SCALE: str = "尺度恢复"
|
||||
LABEL_CHECK_BUTTON_PRESS_EVENT: str = "button_press_event"
|
||||
LABEL_CHECK_BUTTON_RELEASE_EVENT: str = "button_release_event"
|
||||
LABEL_CHECK_MOTION_NOTIFY_EVENT: str = "motion_notify_event"
|
||||
LABEL_CHECK_ADD_POINTS_SUCCESSFULLY: str = "成功新增点,横坐标:"
|
||||
LABEL_CHECK_REMOVE_POINTS_SUCCESSFULLY: str = "成功删除点,横坐标:"
|
||||
LABEL_CHECK_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无新增或删除点"
|
||||
LABEL_CHECK_CUSTOM_NAVIGATIONTOOLBAR_WIDGET_NAME: str = "MainWindow"
|
||||
LABEL_CHECK_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({ConfigParams.LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
|
||||
|
||||
|
||||
# 体动打标
|
||||
ARTIFACT_LABEL_FILES_NOT_FOUND: str = f"无法找到{ConfigParams.ARTIFACT_LABEL_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}或{ConfigParams.ARTIFACT_LABEL_INPUT_XINXIAO_FILENAME}{ConfigParams.ENDSWITH_TXT},无法执行<体动标注>"
|
||||
ARTIFACT_LABEL_FILES_FOUND: str = f"找到{ConfigParams.ARTIFACT_LABEL_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}和{ConfigParams.ARTIFACT_LABEL_INPUT_XINXIAO_FILENAME}{ConfigParams.ENDSWITH_TXT}"
|
||||
ARTIFACT_LABEL_HISTORICAL_SAVE_FOUND: str = "找到历史存档文件,已成功读取"
|
||||
|
||||
ARTIFACT_LABEL_RUNNING: str = "开始执行任务<体动标注>"
|
||||
ARTIFACT_LABEL_INPUT_FAILURE_LENGTH: str = "导入失败,两个输入信号的长度不相等"
|
||||
ARTIFACT_LABEL_INPUT_ARTIFACT_FAILURE_FORMAT: str = "导入体动失败,请检查体动标签格式"
|
||||
ARTIFACT_LABEL_INPUT_ARTIFACT_FAILURE_LENGTH: str = "导入体动失败,请检查体动长度是否为4的倍数"
|
||||
ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY: str = "体动被删除"
|
||||
ARTIFACT_LABEL_DELETE_ARTIFACT_FAILURE: str = "需要被删除的体动不存在"
|
||||
ARTIFACT_LABEL_JUMP_ARTIFACT: str = "跳转到体动"
|
||||
ARTIFACT_LABEL_MISS_ARGS: str = "打标参数未填写"
|
||||
ARTIFACT_LABEL_OVERLAPPING: str = "当前所打标的片段存在重合,重合片段序号:"
|
||||
ARTIFACT_LABEL_COLUMN_ORGBCG_SYNC: str = "orgBcg_sync"
|
||||
ARTIFACT_LABEL_COLUMN_BCG_SYNC: str = "BCG_sync"
|
||||
ARTIFACT_LABEL_AUTOPLAY_LEFT: str = "LEFT"
|
||||
ARTIFACT_LABEL_AUTOPLAY_PAUSE: str = "PAUSE"
|
||||
ARTIFACT_LABEL_AUTOPLAY_RIGHT: str = "RIGHT"
|
||||
ARTIFACT_LABEL_AUTOPLAY_LEFT_INFO: str = "开始自动播放-向左"
|
||||
ARTIFACT_LABEL_AUTOPLAY_PAUSE_INFO: str = "暂停自动播放"
|
||||
ARTIFACT_LABEL_AUTOPLAY_RIGHT_INFO: str = "开始自动播放-向右"
|
||||
ARTIFACT_LABEL_RECOVER_SCALE: str = "尺度恢复"
|
||||
ARTIFACT_LABEL_BUTTON_PRESS_EVENT: str = "button_press_event"
|
||||
ARTIFACT_LABEL_BUTTON_RELEASE_EVENT: str = "button_release_event"
|
||||
ARTIFACT_LABEL_MOTION_NOTIFY_EVENT: str = "motion_notify_event"
|
||||
ARTIFACT_LABEL_AUTOPLAY_PRESET1_INFO: str = "切换到自动播放-预设1"
|
||||
ARTIFACT_LABEL_AUTOPLAY_PRESET2_INFO: str = "切换到自动播放-预设2"
|
||||
ARTIFACT_LABEL_AUTOPLAY_PRESET3_INFO: str = "切换到自动播放-预设3"
|
||||
ARTIFACT_LABEL_AUTOPLAY_PRESET_CUSTOM_INFO: str = "切换到自动播放-自定义"
|
||||
ARTIFACT_LABEL_CUSTOM_NAVIGATIONTOOLBAR_WIDGET_NAME: str = "MainWindow"
|
||||
ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_NAME: str = f"标注体动({ConfigParams.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY})"
|
||||
ARTIFACT_LABEL_LABELBTN_STYLE_1: str = """
|
||||
QPushButton {
|
||||
background-color: #ffa500; /* 设置背景颜色 */
|
||||
padding: 10px; /* 设置内边距 */
|
||||
border: 2px solid darkblue; /* 设置边框 */
|
||||
border-radius: 10px; /* 设置圆角 */
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #00ff00; /* 鼠标悬停时的背景颜色 */
|
||||
}"""
|
||||
ARTIFACT_LABEL_LABELBTN_STYLE_2: str = """
|
||||
QPushButton {
|
||||
background-color: #ffff00; /* 设置背景颜色 */
|
||||
padding: 10px; /* 设置内边距 */
|
||||
border: 2px solid darkblue; /* 设置边框 */
|
||||
border-radius: 10px; /* 设置圆角 */
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #00ff00; /* 鼠标悬停时的背景颜色 */
|
||||
}"""
|
||||
ARTIFACT_LABEL_LABELBTN_STYLE_3: str = """
|
||||
QPushButton {
|
||||
background-color: #00ffff; /* 设置背景颜色 */
|
||||
padding: 10px; /* 设置内边距 */
|
||||
border: 2px solid darkblue; /* 设置边框 */
|
||||
border-radius: 10px; /* 设置圆角 */
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #00ff00; /* 鼠标悬停时的背景颜色 */
|
||||
}"""
|
||||
ARTIFACT_LABEL_LABELBTN_STYLE_4: str = """
|
||||
QPushButton {
|
||||
background-color: #ee82ee; /* 设置背景颜色 */
|
||||
padding: 10px; /* 设置内边距 */
|
||||
border: 2px solid darkblue; /* 设置边框 */
|
||||
border-radius: 10px; /* 设置圆角 */
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #00ff00; /* 鼠标悬停时的背景颜色 */
|
||||
}"""
|
||||
ARTIFACT_LABEL_LABELBTN_STYLE_5: str = """
|
||||
QPushButton {
|
||||
background-color: #808080; /* 设置背景颜色 */
|
||||
padding: 10px; /* 设置内边距 */
|
||||
border: 2px solid darkblue; /* 设置边框 */
|
||||
border-radius: 10px; /* 设置圆角 */
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #00ff00; /* 鼠标悬停时的背景颜色 */
|
||||
}"""
|
||||
|
||||
|
||||
# 质量打标
|
||||
BCG_QUALITY_LABEL_FILES_NOT_FOUND: str = f"无法找到{ConfigParams.BCG_QUALITY_LABEL_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}或{ConfigParams.BCG_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT},无法执行<BCG的质量标注>"
|
||||
BCG_QUALITY_LABEL_FILES_FOUND: str = f"找到{ConfigParams.BCG_QUALITY_LABEL_INPUT_BCG_FILENAME}{ConfigParams.ENDSWITH_TXT}和{ConfigParams.BCG_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT}"
|
||||
BCG_QUALITY_LABEL_HISTORICAL_SAVE_FOUND: str = f"找到历史存档文件{ConfigParams.BCG_QUALITY_LABEL_SAVE_FILENAME}{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_10S}{ConfigParams.ENDSWITH_CSV}或{ConfigParams.BCG_QUALITY_LABEL_SAVE_FILENAME}{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_30S}{ConfigParams.ENDSWITH_CSV},已成功读取"
|
||||
BCG_QUALITY_LABEL_MODE_UNSELECTED: str = "显示模式未选择"
|
||||
BCG_QUALITY_LABEL_INPUT_SIGNAL_FAILURE: str = "导入信号失败,请检查信号长度"
|
||||
BCG_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_FORMAT: str = "导入体动失败,请检查体动标签格式"
|
||||
BCG_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_LENGTH: str = "导入体动失败,请检查体动长度是否为4的倍数"
|
||||
|
||||
BCG_QUALITY_LABEL_RUNNING: str = "开始执行任务<BCG的质量评估标注>"
|
||||
BCG_QUALITY_LABEL_10S_MODE: str = f"{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_10S}_MODE"
|
||||
BCG_QUALITY_LABEL_30S_MODE: str = f"{ConfigParams.BCG_QUALITY_LABEL_SAVE_MODE_30S}_MODE"
|
||||
BCG_QUALITY_LABEL_COLUMN_LABEL: str = "label"
|
||||
BCG_QUALITY_LABEL_COLUMN_REMARK: str = "remark"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_FIRST_PART: str = "你正在查看第1段信号"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_LAST_PART: str = "你正在查看最后1段信号"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_FIRST_PART_UNLABELED: str = "前面的片段都被打标,将跳转至第1段信号"
|
||||
BCG_QUALITY_LABEL_VIEWING_THE_LAST_PART_UNLABELED: str = "后面的片段都被打标,将跳转至最后1段信号"
|
||||
BCG_QUALITY_LABEL_LABELED_FINISHED: str = "该份数据打标已全部完成"
|
||||
BCG_QUALITY_LABEL_VIEWING_PART: str = "正在查看信号段"
|
||||
BCG_QUALITY_LABEL_JUMP_PART: str = "跳转到片段"
|
||||
BCG_QUALITY_LABEL_CLICKED_CHECKBOX_HIGHLIGHT_LONGEST_CONTINUOUS: str = "点击了<高亮最长连续>"
|
||||
BCG_QUALITY_LABEL_CLICKED_CHECKBOX_DISPLAY_AFTERFILTER: str = "点击了<去除工频噪声>"
|
||||
BCG_QUALITY_LABEL_CLICKED_CHECKBOX_EXAMINE_TOBOLABELED: str = "点击了<仅查未标片段>"
|
||||
BCG_QUALITY_LABEL_LABEL_ALL_TO_TYPE_C_QUESTION_CONTENT: str = "你确定要将所有片段标记为类型C"
|
||||
BCG_QUALITY_LABEL_LABEL_ALL_TO_TYPE_C: str = "已将所有片段标记为类型C"
|
||||
BCG_QUALITY_LABEL_LABEL_ARTIFACT_TO_TYPE_C_QUESTION_CONTENT: str = "你确定要将所有带有体动的片段标记为类型C"
|
||||
BCG_QUALITY_LABEL_LABEL_ARTIFACT_TO_TYPE_C: str = "已将所有带有体动的片段标记为类型C"
|
||||
BCG_QUALITY_LABEL_PLOT_LABEL_SIGNAL: str = "BCG"
|
||||
BCG_QUALITY_LABEL_PLOT_LABEL_ARTIFACT: str = "Artifact"
|
||||
BCG_QUALITY_LABEL_PLOT_LABEL_LONGEST_CONTINUOUS: str = "Longest_Continuous"
|
||||
BCG_QUALITY_LABEL_10S_A: str = "a"
|
||||
BCG_QUALITY_LABEL_10S_B: str = "b"
|
||||
BCG_QUALITY_LABEL_10S_C: str = "c"
|
||||
BCG_QUALITY_LABEL_10S_A_LIST: str = "label_a"
|
||||
BCG_QUALITY_LABEL_10S_B_LIST: str = "label_b"
|
||||
BCG_QUALITY_LABEL_10S_C_LIST: str = "label_c"
|
||||
BCG_QUALITY_LABEL_30S_A1: str = "a"
|
||||
BCG_QUALITY_LABEL_30S_A2: str = "b"
|
||||
BCG_QUALITY_LABEL_30S_B1: str = "c"
|
||||
BCG_QUALITY_LABEL_30S_B2: str = "d"
|
||||
BCG_QUALITY_LABEL_30S_C: str = "e"
|
||||
BCG_QUALITY_LABEL_30S_A1_LIST: str = "label_a1"
|
||||
BCG_QUALITY_LABEL_30S_A2_LIST: str = "label_a2"
|
||||
BCG_QUALITY_LABEL_30S_B1_LIST: str = "label_b1"
|
||||
BCG_QUALITY_LABEL_30S_B2_LIST: str = "label_b2"
|
||||
BCG_QUALITY_LABEL_30S_C_LIST: str = "label_c"
|
||||
BCG_QUALITY_LABEL_tobeLabeled: str = "f"
|
||||
BCG_QUALITY_LABEL_tobeLabeled_LIST: str = "label_tobeLabeled"
|
||||
BCG_QUALITY_LABEL_LABELBTN_STYLE: str = """
|
||||
QPushButton {
|
||||
background-color: orange; /* 设置背景颜色 */
|
||||
padding: 10px; /* 设置内边距 */
|
||||
border: 2px solid darkblue; /* 设置边框 */
|
||||
border-radius: 10px; /* 设置圆角 */
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: yellow; /* 鼠标悬停时的背景颜色 */
|
||||
}"""
|
||||
|
||||
|
||||
# 呼吸可用性及间期标注
|
||||
RESP_QUALITY_LABEL_FILES_NOT_FOUND: str = f"无法找到{ConfigParams.RESP_QUALITY_LABEL_INPUT_XINXIAO_FILENAME}{ConfigParams.ENDSWITH_TXT}或{ConfigParams.RESP_QUALITY_LABEL_INPUT_THO_FILENAME}{ConfigParams.ENDSWITH_TXT}或{ConfigParams.RESP_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT},无法执行<呼吸可用性及间期标注>"
|
||||
RESP_QUALITY_LABEL_FILES_FOUND: str = f"找到{ConfigParams.RESP_QUALITY_LABEL_INPUT_XINXIAO_FILENAME}{ConfigParams.ENDSWITH_TXT}和{ConfigParams.RESP_QUALITY_LABEL_INPUT_THO_FILENAME}{ConfigParams.ENDSWITH_TXT}和{ConfigParams.RESP_QUALITY_LABEL_INPUT_ARTIFACT_FILENAME}{ConfigParams.ENDSWITH_TXT}"
|
||||
RESP_QUALITY_LABEL_HISTORICAL_SAVE1_FOUND: str = f"找到历史存档文件{ConfigParams.RESP_QUALITY_LABEL_SAVE_RESP_QUALITY_LABNEL_FILENAME}{ConfigParams.ENDSWITH_TXT},已成功读取"
|
||||
RESP_QUALITY_LABEL_HISTORICAL_SAVE2_FOUND: str = f"找到历史存档文件{ConfigParams.RESP_QUALITY_LABEL_SAVE_THO_PEAK_FILENAME}{ConfigParams.ENDSWITH_TXT},已成功读取"
|
||||
RESP_QUALITY_LABEL_INPUT_SIGNAL_FAILURE: str = "导入信号失败,请检查信号长度"
|
||||
RESP_QUALITY_LABEL_INPUT_SUCCESSFULLY: str = "导入数据成功"
|
||||
RESP_QUALITY_LABEL_PREPROCESS_SUCCESSFULLY: str = "导入数据成功"
|
||||
RESP_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_FORMAT: str = "导入体动失败,请检查体动标签格式"
|
||||
RESP_QUALITY_LABEL_INPUT_ARTIFACT_FAILURE_LENGTH: str = "导入体动失败,请检查体动长度是否为4的倍数"
|
||||
|
||||
RESP_QUALITY_LABEL_RUNNING: str = "开始执行任务<呼吸可用性及间期标注>"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_ORGBCG: str = "BDR_sync by filter orgBcg_sync"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_THO: str = "THO_sync after preprocess"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_THO_PEAKS: str = "THO_peak"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_ARTIFACT: str = "Artifact"
|
||||
RESP_QUALITY_LABEL_VIEWING_THE_FIRST_PART: str = "你正在查看第1段信号"
|
||||
RESP_QUALITY_LABEL_VIEWING_THE_LAST_PART: str = "你正在查看最后1段信号"
|
||||
RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_NAME: str = f"批量更改标签({ConfigParams.RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY})"
|
||||
RESP_QUALITY_LABEL_CUSTOM_NAVIGATIONTOOLBAR_WIDGET_NAME: str = "MainWindow"
|
||||
RESP_QUALITY_LABEL_BUTTON_PRESS_EVENT: str = "button_press_event"
|
||||
RESP_QUALITY_LABEL_BUTTON_RELEASE_EVENT: str = "button_release_event"
|
||||
RESP_QUALITY_LABEL_MOTION_NOTIFY_EVENT: str = "motion_notify_event"
|
||||
RESP_QUALITY_LABEL_ADD_POINTS_SUCCESSFULLY: str = "成功新增点,横坐标:"
|
||||
RESP_QUALITY_LABEL_REMOVE_POINTS_SUCCESSFULLY: str = "成功删除点,横坐标:"
|
||||
RESP_QUALITY_LABEL_NO_POINT_IN_THE_INTERVAL: str = "所选区间内无新增或删除点"
|
||||
RESP_QUALITY_LABEL_SAVE_PEAKS_SUCCESSFULLY: str = "保存峰值成功"
|
||||
RESP_QUALITY_LABEL_DATA_NOT_FOUND: str = "数据未导入"
|
||||
RESP_QUALITY_LABEL_LABEL_SUCCESSFULLY: str = "片段标注并保存成功"
|
||||
RESP_QUALITY_LABEL_RESET_SUCCESSFULLY: str = "片段重置并保存成功"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_VLINE: str = "vline"
|
||||
RESP_QUALITY_LABEL_PLOT_LABEL_HLINE: str = "hline"
|
||||
RESP_QUALITY_LABEL_A_QUALITY: int = 1
|
||||
RESP_QUALITY_LABEL_B_QUALITY: int = 0
|
||||
RESP_QUALITY_LABEL_C_QUALITY: int = -1
|
||||
RESP_QUALITY_LABEL_LABELED: str = "已标注"
|
||||
RESP_QUALITY_LABEL_TOBELABELED: str = "未标注"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_BDR_TITLE: str = "Spectrum of BDR_sync by filter orgBcg_sync"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_THO_TITLE: str = "Spectrum of THO_sync after preprocess"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_ORGBCG_LABEL: str = "orgBcg"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_BDR_LABEL: str = "BDR"
|
||||
RESP_QUALITY_LABEL_SPECTRUM_THO_LABEL: str = "THO"
|
||||
RESP_QUALITY_LABEL_CUSTOM_FILTER_ARGS_ERROR: str = "orgBcg带通滤波频率设置范围应为数字,范围是0~1"
|
||||
RESP_QUALITY_LABEL_AUTOLABEL_ARGS_ERROR: str = "人工标注阈值设置范围应为数字,范围是0~1"
|
||||
RESP_QUALITY_LABEL_CHECK_ARGS_QUESTION_CONTENT: str = "你确定要执行此操作吗,请确保参数输入正确"
|
||||
RESP_QUALITY_LABEL_KEY_VALUE = {
|
||||
1: "Good",
|
||||
0: "Bad",
|
||||
-1: "None"
|
||||
}
|
||||
|
||||
|
||||
# 睡眠呼吸暂停事件打标
|
||||
SA_LABEL_CHANNEL_NAME_FLOWT: str = "Flow T"
|
||||
SA_LABEL_CHANNEL_NAME_FLOWP: str = "Flow P"
|
||||
SA_LABEL_CHANNEL_NAME_EFFORTTHO: str = "Effort Tho"
|
||||
SA_LABEL_CHANNEL_NAME_EFFORTABD: str = "Effort Abd"
|
||||
SA_LABEL_CHANNEL_NAME_SPO2: str = "SpO2"
|
||||
|
||||
|
||||
|
||||
|
||||
# 禁止实例化
|
||||
def __new__(cls):
|
||||
raise TypeError("Constants class cannot be instantiated")
|
||||
|
||||
# 禁止修改常量
|
||||
@classmethod
|
||||
def __setattr__(cls, key, value):
|
||||
raise AttributeError("Cannot modify constants")
|
||||
61
func/utils/CustomException.py
Normal file
61
func/utils/CustomException.py
Normal file
@ -0,0 +1,61 @@
|
||||
from logging import error
|
||||
|
||||
class TipsTypeValueNotExistError(Exception):
|
||||
"""日志类型参数不存在异常"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
error("日志类型参数不存在异常")
|
||||
|
||||
class MsgBoxTypeValueNotExistError(Exception):
|
||||
"""MsgBox弹窗类型参数不存在异常"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
error("MsgBox弹窗类型参数不存在异常")
|
||||
|
||||
class PreprocessModeNotExistError(Exception):
|
||||
"""预处理类型不存在异常"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
error("预处理类型不存在异常")
|
||||
|
||||
class RPeakDetectMethodNotExistError(Exception):
|
||||
"""R峰算法定位检测方法不存在异常"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
error("R峰提取检测方法不存在异常")
|
||||
|
||||
class JPeakDetectMethodsError(Exception):
|
||||
"""J峰算法定位检测方法选择异常"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
error("J峰算法定位检测方法选择异常")
|
||||
|
||||
class LabelCheckModeNotExistError(Exception):
|
||||
"""人工纠正类型不存在异常"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
error("人工纠正类型不存在异常")
|
||||
|
||||
class ArtifactLabelUnknownError(Exception):
|
||||
"""体动标注未知异常"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
error("体动打标未知异常")
|
||||
|
||||
class BCGQualityLabelTableWidgetNotExistError(Exception):
|
||||
"""BCG质量标注表格元素不存在异常"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
error("BCG质量标注表格元素不存在异常")
|
||||
|
||||
class RespQualityLabelOutOfIndexError(Exception):
|
||||
"""呼吸可用性及间期标注数组越界异常"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
error("呼吸可用性及间期标注数组越界异常")
|
||||
|
||||
class RespQualityLabelTableWidgetNotExistError(Exception):
|
||||
"""呼吸可用性及间期标注表格元素不存在异常"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
error("呼吸可用性及间期标注表格元素不存在异常")
|
||||
96
func/utils/PublicFunc.py
Normal file
96
func/utils/PublicFunc.py
Normal file
@ -0,0 +1,96 @@
|
||||
from datetime import datetime
|
||||
from logging import error, info
|
||||
|
||||
from PySide6.QtWidgets import QMessageBox
|
||||
|
||||
from func.utils.Constants import Constants
|
||||
from func.utils.CustomException import TipsTypeValueNotExistError, MsgBoxTypeValueNotExistError
|
||||
|
||||
|
||||
class PublicFunc:
|
||||
|
||||
@staticmethod
|
||||
def get_current_localtime() -> str:
|
||||
"""
|
||||
获取当前本地时间
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
str,格式化为"%H:%M:%S"的当前本地时间
|
||||
|
||||
Raises:
|
||||
"""
|
||||
return str(datetime.now().strftime("%H:%M:%S"))
|
||||
|
||||
@staticmethod
|
||||
def format_status_msg(msg) -> str:
|
||||
"""
|
||||
格式化状态栏信息
|
||||
|
||||
Parameters:
|
||||
msg - str,需要被格式化的字符串
|
||||
|
||||
Returns:
|
||||
str,格式化为"%H:%M:%S"的当前本地时间 + 信息
|
||||
|
||||
Raises:
|
||||
"""
|
||||
return str(datetime.now().strftime("%H:%M:%S")) + " " + msg
|
||||
|
||||
@staticmethod
|
||||
def text_output(main_window: object, content: str, tips_type: str) -> None:
|
||||
"""
|
||||
更新textBrowser中的内容,同时输出日志
|
||||
|
||||
Parameters:
|
||||
main_window - object,Qt的含有textBrowser属性的对象,这里一般指的是mainWindow,里面有唯一的textBrowser属性
|
||||
content - str,需要输出的内容
|
||||
tips_type - 日志输出的类型
|
||||
|
||||
Returns:
|
||||
|
||||
Raises:
|
||||
TipsTypeValueNotExistError
|
||||
"""
|
||||
if tips_type is Constants.TIPS_TYPE_INFO:
|
||||
info(f"{tips_type}: {content}")
|
||||
main_window.textBrowser_info.append(
|
||||
f"<font color='black'>{PublicFunc.get_current_localtime()} {tips_type}: {content}</font>")
|
||||
elif tips_type is Constants.TIPS_TYPE_ERROR:
|
||||
error(f"{tips_type}: {content}")
|
||||
main_window.textBrowser_info.append(
|
||||
f"<font color='red'>{PublicFunc.get_current_localtime()} {tips_type}: {content}</font>")
|
||||
else:
|
||||
raise TipsTypeValueNotExistError()
|
||||
|
||||
main_window.textBrowser_info.verticalScrollBar().setValue(
|
||||
main_window.textBrowser_info.verticalScrollBar().maximum())
|
||||
|
||||
@staticmethod
|
||||
def msgbox_output(main_window: object, content: str, msg_box_type: str) -> None:
|
||||
"""
|
||||
更新messageBox中的内容,并弹出
|
||||
|
||||
Parameters:
|
||||
main_window - object,Qt的含有messageBox属性的对象,这里一般指的是mainWindow,里面有唯一的messageBox属性
|
||||
content - str,需要输出的内容
|
||||
msg_box_type - str,messageBox弹窗的类型
|
||||
|
||||
Returns:
|
||||
|
||||
Raises:
|
||||
MsgBoxTypeValueNotExistError
|
||||
"""
|
||||
main_window.msgBox.setText(f"{msg_box_type}: {content}")
|
||||
if msg_box_type is Constants.MSGBOX_TYPE_INFO:
|
||||
main_window.msgBox.setIcon(QMessageBox.Information)
|
||||
elif msg_box_type is Constants.MSGBOX_TYPE_WARNING:
|
||||
main_window.msgBox.setIcon(QMessageBox.Warning)
|
||||
elif msg_box_type is Constants.MSGBOX_TYPE_ERROR:
|
||||
main_window.msgBox.setIcon(QMessageBox.Critical)
|
||||
elif msg_box_type is Constants.MSGBOX_TYPE_QUESTION:
|
||||
main_window.msgBox.setIcon(QMessageBox.Question)
|
||||
else:
|
||||
raise MsgBoxTypeValueNotExistError()
|
||||
main_window.msgBox.exec()
|
||||
295
func/utils/detect_Jpeak.py
Normal file
295
func/utils/detect_Jpeak.py
Normal file
@ -0,0 +1,295 @@
|
||||
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
|
||||
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 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):
|
||||
orgBCG = test_data
|
||||
operation = BCG_Operation()
|
||||
# 降采样
|
||||
orgBCG = operation.down_sample(orgBCG, down_radio=int(fs//100)).copy() #一开始没加.copy()会报错,后来加了就没事了,结果没影响
|
||||
# plt.figure()
|
||||
# plt.plot(orgBCG)
|
||||
# plt.show()
|
||||
orgBCG = orgBCG.reshape(-1, 1000)
|
||||
# test dataset
|
||||
orgData = FloatTensor(orgBCG).unsqueeze(1)
|
||||
# predict
|
||||
if useCPU == True:
|
||||
gpu = False
|
||||
device = torch_device("cpu")
|
||||
else:
|
||||
gpu = is_available()
|
||||
device = torch_device("cuda" if is_available() else "cpu")
|
||||
# if gpu:
|
||||
# orgData = orgData.cuda()
|
||||
# model.cuda()
|
||||
orgData = orgData.to(device)
|
||||
model = model.to(device)
|
||||
|
||||
with no_grad():
|
||||
y_hat = model(orgData)
|
||||
y_prob = sigmoid(y_hat)
|
||||
beat = (y_prob>0.5).float().view(-1).cpu().data.numpy()
|
||||
beat_diff = diff(beat)
|
||||
up_index = argwhere(beat_diff==1)
|
||||
down_index = argwhere(beat_diff==-1)
|
||||
|
||||
return beat,up_index,down_index,y_prob
|
||||
|
||||
def find_TPeak(data,peaks,th=50):
|
||||
"""
|
||||
找出真实的J峰或R峰
|
||||
:param data: BCG或ECG数据
|
||||
:param peaks: 初步峰值(从label中导出的location_R)
|
||||
:param th: 范围阈值
|
||||
:return: 真实峰值
|
||||
"""
|
||||
return_peak = []
|
||||
for peak in peaks:
|
||||
if peak>len(data):continue
|
||||
min_win,max_win = max(0,int(peak-th)),min(len(data),int(peak+th))
|
||||
return_peak.append(argmax(data[min_win:max_win])+min_win)
|
||||
return return_peak
|
||||
|
||||
def new_calculate_beat(y,predict,th=0.5,up=10,th1=100,th2=45): #通过预测计算回原来J峰的坐标 输入:y_prob,predict=ture,up*10,降采样多少就乘多少
|
||||
"""
|
||||
加上不应期算法,消除误判的峰
|
||||
:param y: 预测输出值或者标签值(label)
|
||||
:param predict: ture or false
|
||||
:param up: 降采样为多少就多少
|
||||
:return: 预测的J峰位置
|
||||
"""
|
||||
if predict:
|
||||
beat = where(y>th,1,0)
|
||||
else:
|
||||
beat = y
|
||||
beat_diff = diff(beat) #一阶差分
|
||||
up_index = argwhere(beat_diff == 1).reshape(-1)
|
||||
down_index = argwhere(beat_diff == -1).reshape(-1)
|
||||
# print(up_index,down_index)
|
||||
# print(y)
|
||||
|
||||
# print(y[up_index[4]+1:down_index[4]+1])
|
||||
|
||||
if len(up_index)==0:
|
||||
return [0]
|
||||
if up_index[0] > down_index[0]:
|
||||
down_index = delete(down_index, 0)
|
||||
if up_index[-1] > down_index[-1]:
|
||||
up_index = delete(up_index, -1)
|
||||
|
||||
"""
|
||||
加上若大于130点都没有一个心跳时,降低阈值重新判决一次,一般降到0.3就可以了;; 但是对于体动片段降低阈值可能又会造成误判,而且出现体动的话会被丢弃,间隔时间也长
|
||||
"""
|
||||
# print("初始:",up_index.shape,down_index.shape)
|
||||
i = 0
|
||||
lenth1 = len(up_index)
|
||||
while i < len(up_index)-1:
|
||||
if abs(up_index[i+1]-up_index[i]) > th1:
|
||||
re_prob = y[down_index[i]+15:up_index[i+1]-15] #原本按正常应该是两个都+1的,但是由于Unet输出低于0.6时,把阈值调小后会在附近一两个点也变为1,会影响判断
|
||||
# print(re_prob.shape)
|
||||
beat1 = where(re_prob > 0.1, 1, 0)
|
||||
# print(beat1)
|
||||
if sum(beat1) != 0 and beat1[0] != 1 and beat1[-1] != 1:
|
||||
insert_up_index,insert_down_index = add_beat(re_prob,th=0.1)
|
||||
# print(insert_up_index,insert_down_index,i)
|
||||
if len(insert_up_index) > 1:
|
||||
l = i+1
|
||||
|
||||
for u,d in zip(insert_up_index,insert_down_index):
|
||||
up_index = insert(up_index,l,u+down_index[i]+1+15) #np.insert(arr, obj, values, axis) arr原始数组,可一可多,obj插入元素位置,values是插入内容,axis是按行按列插入。
|
||||
down_index = insert(down_index,l,d+down_index[i]+1+15)
|
||||
l = l+1
|
||||
# print('l=', l)
|
||||
elif len(insert_up_index) == 1:
|
||||
# print(i)
|
||||
up_index = insert(up_index,i+1,down_index[i]+insert_up_index+1+15)
|
||||
down_index = insert(down_index,i+1,down_index[i]+insert_down_index+1+15)
|
||||
i = i + len(insert_up_index) + 1
|
||||
else:
|
||||
i = i+1
|
||||
continue
|
||||
else:
|
||||
i = i+1
|
||||
# print("最终:",up_index.shape,down_index.shape)
|
||||
|
||||
"""
|
||||
添加不应期
|
||||
"""
|
||||
new_up_index = up_index
|
||||
new_down_index = down_index
|
||||
flag = 0
|
||||
i = 0
|
||||
lenth = len(up_index)
|
||||
while i < lenth:
|
||||
if abs(up_index[i+1]-up_index[i]) < th2:
|
||||
prob_forward = y[up_index[i]+1:down_index[i]+1]
|
||||
prob_backward = y[up_index[i+1]+1:down_index[i+1]+1]
|
||||
|
||||
forward_score = 0
|
||||
back_score = 0
|
||||
|
||||
forward_count = down_index[i] - up_index[i]
|
||||
back_count = down_index[i+1] - up_index[i+1]
|
||||
|
||||
forward_max = np_max(prob_forward)
|
||||
back_max = np_max(prob_backward)
|
||||
|
||||
forward_min = np_min(prob_forward)
|
||||
back_min = np_min(prob_backward)
|
||||
|
||||
forward_average = mean(prob_forward)
|
||||
back_average = mean(prob_backward)
|
||||
|
||||
if forward_count > back_count:
|
||||
forward_score = forward_score + 1
|
||||
else:back_score = back_score + 1
|
||||
|
||||
if forward_max > back_max:
|
||||
forward_score = forward_score + 1
|
||||
else:back_score = back_score + 1
|
||||
|
||||
if forward_min < back_min:
|
||||
forward_score = forward_score + 1
|
||||
else:back_score = back_score + 1
|
||||
|
||||
if forward_average > back_average:
|
||||
forward_score = forward_score + 1
|
||||
else:back_score = back_score + 1
|
||||
|
||||
if forward_score >=3:
|
||||
up_index = delete(up_index, i+1)
|
||||
down_index = delete(down_index, i+1)
|
||||
flag = 1
|
||||
elif back_score >=3:
|
||||
up_index = delete(up_index, i)
|
||||
down_index = delete(down_index, i)
|
||||
flag = 1
|
||||
elif forward_score == back_score:
|
||||
if forward_average > back_average:
|
||||
up_index = delete(up_index, i + 1)
|
||||
down_index = delete(down_index, i + 1)
|
||||
flag = 1
|
||||
else:
|
||||
up_index = delete(up_index, i)
|
||||
down_index = delete(down_index, i)
|
||||
flag = 1
|
||||
if flag == 1:
|
||||
i = i
|
||||
flag = 0
|
||||
else: i = i+1
|
||||
|
||||
else:i = i + 1
|
||||
|
||||
if i > len(up_index)-2:
|
||||
break
|
||||
# elif abs(up_index[i+1]-up_index[i]) > 120:
|
||||
# print("全部处理之后",up_index.shape,down_index.shape)
|
||||
predict_J = (up_index.reshape(-1) + down_index.reshape(-1)) // 2*up
|
||||
# predict_J = predict_J.astype(int)
|
||||
|
||||
return predict_J
|
||||
|
||||
def add_beat(y,th=0.2): #通过预测计算回原来J峰的坐标 输入:y_prob,predict=ture,up*10,降采样多少就乘多少
|
||||
"""
|
||||
:param y: 预测输出值或者标签值(label)
|
||||
:param predict: ture or false
|
||||
:param up: 降采样为多少就多少
|
||||
:return: 预测的J峰位置
|
||||
"""
|
||||
beat1 = where(y>th,1,0)
|
||||
beat_diff1 = diff(beat1) #一阶差分
|
||||
add_up_index = argwhere(beat_diff1 == 1).reshape(-1)
|
||||
add_down_index = argwhere(beat_diff1 == -1).reshape(-1)
|
||||
# print(beat1)
|
||||
# print(add_up_index,add_down_index)
|
||||
if len(add_up_index) > 0:
|
||||
if add_up_index[0] > add_down_index[0]:
|
||||
add_down_index = delete(add_down_index, 0)
|
||||
if add_up_index[-1] > add_down_index[-1]:
|
||||
add_up_index = delete(add_up_index, -1)
|
||||
return add_up_index, add_down_index
|
||||
else:
|
||||
return 0
|
||||
|
||||
def calculate_beat(y,predict,th=0.5,up=10): #通过预测计算回原来J峰的坐标 输入:y_prob,predict=ture,up*10,降采样多少就乘多少
|
||||
"""
|
||||
:param y: 预测输出值或者标签值(label)
|
||||
:param predict: ture or false
|
||||
:param up: 降采样为多少就多少
|
||||
:return: 预测的J峰位置
|
||||
"""
|
||||
if predict:
|
||||
beat = where(y>th,1,0)
|
||||
else:
|
||||
beat = y
|
||||
beat_diff = diff(beat) #一阶差分
|
||||
up_index = argwhere(beat_diff == 1).reshape(-1)
|
||||
down_index = argwhere(beat_diff == -1).reshape(-1)
|
||||
if len(up_index)==0:
|
||||
return [0]
|
||||
if up_index[0] > down_index[0]:
|
||||
down_index = delete(down_index, 0)
|
||||
if up_index[-1] > down_index[-1]:
|
||||
up_index = delete(up_index, -1)
|
||||
predict_J = (up_index.reshape(-1) + down_index.reshape(-1)) // 2*up
|
||||
# predict_J = predict_J.astype(int)
|
||||
|
||||
return predict_J
|
||||
|
||||
def preprocess(raw_bcg, fs, low_cut, high_cut, amp_value):
|
||||
bcg_data = raw_bcg[:len(raw_bcg) // (fs * 10) * fs * 10]
|
||||
preprocessing = BCG_Operation(sample_rate=fs)
|
||||
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):
|
||||
|
||||
model_name = get_model_name(str(model_name))
|
||||
if model_name == "Fivelayer_Unet":
|
||||
model = Fivelayer_Unet()
|
||||
elif model_name == "Fivelayer_Lstm_Unet":
|
||||
model = Fivelayer_Lstm_Unet()
|
||||
elif model_name == "Sixlayer_Unet":
|
||||
model = Sixlayer_Unet()
|
||||
elif model_name == "U_net":
|
||||
model = Unet()
|
||||
else:
|
||||
raise Exception
|
||||
model.load_state_dict(load(model_path, map_location=torch_device('cpu')))
|
||||
model.eval()
|
||||
|
||||
# J峰预测
|
||||
beat, up_index, down_index, y_prob = evaluate(bcg_data, model=model, fs=fs, useCPU=useCPU)
|
||||
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)
|
||||
|
||||
predict_J = find_TPeak(bcg_data, predict_J, th=int(peaks_value * fs / 1000))
|
||||
predict_J = array(predict_J)
|
||||
|
||||
Interval = full(len(bcg_data), nan)
|
||||
for i in range(len(predict_J) - 1):
|
||||
Interval[predict_J[i]: predict_J[i + 1]] = predict_J[i + 1] - predict_J[i]
|
||||
|
||||
empty_cache()
|
||||
|
||||
return predict_J, Interval
|
||||
|
||||
def get_model_name(input_string):
|
||||
# 找到最后一个 "_" 的位置
|
||||
last_underscore_index = input_string.rfind('_')
|
||||
|
||||
# 如果没有找到 "_"
|
||||
if last_underscore_index == -1:
|
||||
return input_string # 返回整个字符串
|
||||
|
||||
# 返回最后一个 "_" 之前的部分
|
||||
return input_string[:last_underscore_index]
|
||||
71
func/utils/detect_Rpeak.py
Normal file
71
func/utils/detect_Rpeak.py
Normal file
@ -0,0 +1,71 @@
|
||||
from ecgdetectors import Detectors
|
||||
from numpy import quantile, delete, array, argmax, full, nan
|
||||
|
||||
from func.BCGDataset import BCG_Operation
|
||||
|
||||
def refinement( data, peak):
|
||||
if len(data) == 0 or len(peak) <=2 : return None
|
||||
firstPeak = peak[0]
|
||||
lastPeak = peak[-1]
|
||||
meanPeak = quantile( data[peak[1:-1]], 0.2 )
|
||||
if data[firstPeak] < meanPeak * 0.6 :
|
||||
peak = delete(peak, 0)
|
||||
if data[lastPeak] < meanPeak * 0.6 :
|
||||
peak = delete(peak, -1)
|
||||
return array(peak)
|
||||
|
||||
def find_TPeak(data,peaks,th=50):
|
||||
"""
|
||||
找出真实的J峰或R峰
|
||||
:param data: BCG或ECG数据
|
||||
:param peaks: 初步峰值(从label中导出的location_R)
|
||||
:param th: 范围阈值
|
||||
:return: 真实峰值
|
||||
"""
|
||||
return_peak = []
|
||||
for peak in peaks:
|
||||
if peak>len(data):continue
|
||||
min_win,max_win = max(0,int(peak-th)),min(len(data),int(peak+th))
|
||||
return_peak.append(argmax(data[min_win:max_win])+min_win)
|
||||
return array(return_peak)
|
||||
|
||||
def Rpeak_Detection(raw_ecg,fs,low_cut,high_cut,th1,detector_method):
|
||||
detectors = Detectors(sampling_frequency=fs)
|
||||
method_dic = {'pt': detectors.pan_tompkins_detector,
|
||||
'ta': detectors.two_average_detector,
|
||||
"Engzee": detectors.engzee_detector,
|
||||
"Wt": detectors.swt_detector,
|
||||
"Christov": detectors.christov_detector,
|
||||
"Hamilton": detectors.hamilton_detector
|
||||
}
|
||||
detectormethods = method_dic[detector_method]
|
||||
|
||||
# raw_ecg = raw_ecg[200*sample_rate:]
|
||||
preprocessing = BCG_Operation(sample_rate=fs) # 对ECG做了降采样处理
|
||||
raw_ecg = preprocessing.Butterworth(raw_ecg, "bandpass", low_cut=low_cut, high_cut=high_cut, order=3) * 4
|
||||
#######################限制幅值处理############################################
|
||||
# for i in range(len(raw_ecg)):
|
||||
# if raw_ecg[i] > 300 or raw_ecg[i] < -300:
|
||||
# raw_ecg[i] = 0
|
||||
##############################################################################
|
||||
|
||||
R_peak = array(detectormethods(raw_ecg)) - 100
|
||||
# R_peak = np.array(detectors.pan_tompkins_detector(raw_ecg))-100
|
||||
|
||||
R_peak = find_TPeak(raw_ecg, R_peak, th=int(th1 * fs / 1000))
|
||||
R_peak = refinement(raw_ecg, R_peak)
|
||||
|
||||
RR_Interval = full(len(R_peak) - 1, nan)
|
||||
|
||||
for i in range(len(R_peak) - 1):
|
||||
RR_Interval[i] = R_peak[i + 1] - R_peak[i]
|
||||
|
||||
RRIV = full(len(RR_Interval) - 1, nan)
|
||||
for i in range(len(RR_Interval) - 1):
|
||||
RRIV[i] = RR_Interval[i + 1] - RR_Interval[i]
|
||||
|
||||
Interval = full(len(raw_ecg), nan)
|
||||
for i in range(len(R_peak) - 1):
|
||||
Interval[R_peak[i]: R_peak[i + 1]] = R_peak[i + 1] - R_peak[i]
|
||||
|
||||
return R_peak, Interval, RRIV
|
||||
41
func/utils/resp_quality_label.py
Normal file
41
func/utils/resp_quality_label.py
Normal file
@ -0,0 +1,41 @@
|
||||
from matplotlib.mlab import detrend
|
||||
from numpy import argmax
|
||||
|
||||
from func.utils.resp_quality_label_filter import fft1, bpf, spectral_cosine_similarity
|
||||
|
||||
|
||||
def get_slice(biosignal, seg_idx, duration, fs):
|
||||
"""数据切片"""
|
||||
start = (seg_idx - 1) * duration * fs
|
||||
end = min(seg_idx * duration * fs, len(biosignal))
|
||||
return biosignal[start:end]
|
||||
|
||||
def pre_process(biosignal,fs,fc):
|
||||
"""数据预处理"""
|
||||
biosignal = detrend(biosignal)
|
||||
biosignal = bpf(biosignal, fs, 0.1,fc)
|
||||
return biosignal
|
||||
|
||||
def calculate_spectral_cohere(BCG, THO, fs_bcg,fs_tho):
|
||||
"""计算频谱相似度"""
|
||||
fft_THO, freq_tho = fft1(THO, fs_tho)
|
||||
peak_freq = freq_tho[argmax(fft_THO)]
|
||||
f_low = min(peak_freq-0.2,0.1)
|
||||
f_high = max(peak_freq+0.2,0.1)
|
||||
# 计算频谱相似度
|
||||
Similarity = spectral_cosine_similarity(BCG, THO, fs_bcg, fs_tho,[f_low,f_high])
|
||||
return Similarity
|
||||
|
||||
def evaluate_quality(BCG,THO,fs_bcg,fs_tho,artifact_flag,thresholds):
|
||||
"""评估信号质量"""
|
||||
# 计算信号余弦相似度
|
||||
cohere_value = calculate_spectral_cohere(BCG, THO, fs_bcg, fs_tho)
|
||||
# 质量判断逻辑
|
||||
if cohere_value > thresholds[1]:
|
||||
return 1 if artifact_flag == 0 else -1
|
||||
elif cohere_value < thresholds[0]:
|
||||
BCG = pre_process(BCG, fs_bcg, 0.7)
|
||||
THO = pre_process(THO, fs_tho, 0.7)
|
||||
cohere_value2 = calculate_spectral_cohere(BCG, THO, fs_bcg, fs_tho)
|
||||
return 0 if cohere_value2 < thresholds[0] else -1
|
||||
return -1
|
||||
259
func/utils/resp_quality_label_filter.py
Normal file
259
func/utils/resp_quality_label_filter.py
Normal file
@ -0,0 +1,259 @@
|
||||
from numpy import abs as np_abs, ceil, floor, ndarray, argmax, dot, linalg, where, arange
|
||||
from numpy.fft import fft, fftfreq
|
||||
from scipy.signal import detrend, butter, filtfilt
|
||||
|
||||
|
||||
def fft1(x, fs):
|
||||
"""
|
||||
x: 输入信号
|
||||
fs: 采样频率
|
||||
|
||||
返回:
|
||||
magnitude[mask]:0-1hz信号频谱
|
||||
freq[mask]:0-1hz信号对应频率数组
|
||||
"""
|
||||
N = len(x)
|
||||
# 计算FFT
|
||||
fft_result = fft(x)
|
||||
# 计算幅度谱(取前N//2点,避免镜像)
|
||||
magnitude = np_abs(fft_result)[:N // 2] * 2 / N # 归一化
|
||||
# 生成频率轴
|
||||
freqs = fftfreq(N, 1 / fs)[:N // 2]
|
||||
# 提取0-1Hz范围内的数据
|
||||
mask = freqs <= 1.0 # 筛选条件
|
||||
return magnitude[mask] / max(magnitude[mask]), freqs[mask]
|
||||
|
||||
|
||||
def lpf(input_signal, Fs, Fc):
|
||||
"""
|
||||
巴特沃斯低通滤波器 (零相位滤波)
|
||||
|
||||
参数:
|
||||
input_signal : 输入信号
|
||||
Fs : float - 采样频率 (Hz)
|
||||
Fc : float - 截止频率 (Hz)
|
||||
|
||||
返回:
|
||||
output : ndarray - 滤波后信号
|
||||
"""
|
||||
# 滤波器参数
|
||||
order = 3 # 3阶滤波器
|
||||
nyq = 0.5 * Fs # 奈奎斯特频率
|
||||
|
||||
# 检查截止频率是否有效
|
||||
if Fc <= 0 or Fc >= nyq:
|
||||
raise ValueError("截止频率必须满足 0 < Fc < {} Hz".format(nyq))
|
||||
|
||||
# 去趋势处理
|
||||
data = detrend(input_signal, type='linear')
|
||||
|
||||
# 生成巴特沃斯滤波器系数
|
||||
normal_cutoff = Fc / nyq
|
||||
b, a = butter(order, normal_cutoff, btype='low', analog=False)
|
||||
|
||||
# 零相位滤波
|
||||
output = filtfilt(b, a, data)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def bpf(input_signal, fs, f_low, f_high):
|
||||
"""
|
||||
巴特沃斯带通滤波器 (零相位滤波)
|
||||
|
||||
参数:
|
||||
signal : 输入信号
|
||||
fs : float - 采样频率 (Hz)
|
||||
f_low : float - 下截止频率 (Hz)
|
||||
f_high:float - 上截止频率(Hz)
|
||||
|
||||
返回:
|
||||
output : ndarray - 滤波后信号
|
||||
"""
|
||||
# 滤波器参数
|
||||
order = 2 # 3阶滤波器
|
||||
nyq = 0.5 * fs # 奈奎斯特频率
|
||||
|
||||
# 检查截止频率是否有效
|
||||
if f_low <= 0 or f_high >= nyq:
|
||||
raise ValueError("截止频率必须满足 0 < Fc < {} Hz".format(nyq))
|
||||
|
||||
if f_low >= f_high:
|
||||
raise ValueError("f_low must be less than f_high")
|
||||
|
||||
# 去趋势处理
|
||||
data = detrend(input_signal, type='linear')
|
||||
|
||||
# 生成巴特沃斯滤波器系数
|
||||
fc1 = f_low / nyq
|
||||
fc2 = f_high / nyq
|
||||
b, a = butter(order, [fc1, fc2], btype='bandpass', analog=False)
|
||||
|
||||
# 零相位滤波
|
||||
output = filtfilt(b, a, data)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def detect_peak_bottoms(frequencies, spectrum, peak_idx, left_bound, right_bound):
|
||||
"""
|
||||
检测信号呼吸峰谷
|
||||
参数:
|
||||
frequencies: 频率数组
|
||||
spectrum: 频谱数组
|
||||
peak_idx: 峰值索引
|
||||
left_bound: 左边界
|
||||
right_bound: 右边界
|
||||
返回:
|
||||
f_low:峰谷索引
|
||||
f_high:峰谷索引
|
||||
"""
|
||||
normalized = spectrum / max(spectrum) # 归一化频谱
|
||||
n = len(frequencies)
|
||||
peak_idx = int(peak_idx * n)
|
||||
left_bound = int(left_bound * n)
|
||||
right_bound = int(right_bound * n)
|
||||
|
||||
# 左侧峰底检测
|
||||
left_min = int(ceil(left_bound))
|
||||
for i in range(peak_idx, left_bound - 1, -1):
|
||||
if i == 0:
|
||||
break # 避免索引超出范围
|
||||
if normalized[i] < 0.2 * normalized[peak_idx]:
|
||||
left_min = i
|
||||
break
|
||||
if normalized[i] < normalized[i - 1]:
|
||||
left_min = i
|
||||
|
||||
# 右侧峰底检测
|
||||
right_min = int(floor(right_bound))
|
||||
for i in range(peak_idx, right_bound + 1):
|
||||
if i == n - 1:
|
||||
break # 避免索引超出范围
|
||||
if normalized[i] < 0.2 * normalized[peak_idx]:
|
||||
right_min = i
|
||||
break
|
||||
if normalized[i] > normalized[i + 1] and i != right_bound:
|
||||
right_min = i + 1
|
||||
|
||||
# 结果
|
||||
f_low = max(frequencies[left_min], 0.1)
|
||||
f_high = min(frequencies[right_min], 1)
|
||||
|
||||
return f_low, f_high
|
||||
|
||||
def spectral_cosine_similarity(signal1, signal2, fs1, fs2, freq_range):
|
||||
"""
|
||||
计算两个信号在指定频段内的频谱余弦相似度
|
||||
|
||||
参数:
|
||||
signal1: 信号1
|
||||
signal2: 信号2
|
||||
fs1: 信号1的采样率 (Hz)
|
||||
fs2: 信号2的采样率 (Hz)
|
||||
freq_range: 目标频段 [f_low, f_high] (单位Hz)
|
||||
|
||||
返回:
|
||||
similarity: 指定频段内的频谱余弦相似度 (0~1)
|
||||
"""
|
||||
|
||||
# 参数检查
|
||||
if len(freq_range) != 2 or freq_range[0] >= freq_range[1]:
|
||||
raise ValueError('freq_range应为升序的二元向量 [f_low, f_high]')
|
||||
|
||||
f_low, f_high = freq_range
|
||||
|
||||
# 计算FFT并获取频率轴
|
||||
# 信号1
|
||||
nfft1 = len(signal1)
|
||||
fft_1 = fft(signal1)
|
||||
freq1 = arange(nfft1) * (fs1 / nfft1) # 完整频率轴
|
||||
mag1 = np_abs(fft_1)
|
||||
|
||||
# 信号2
|
||||
nfft2 = len(signal2)
|
||||
fft_2 = fft(signal2)
|
||||
freq2 = arange(nfft2) * (fs2 / nfft2)
|
||||
mag2 = np_abs(fft_2)
|
||||
|
||||
# 提取目标频段的幅度谱
|
||||
idx1 = where((freq1 >= f_low) & (freq1 <= f_high))[0]
|
||||
idx2 = where((freq2 >= f_low) & (freq2 <= f_high))[0]
|
||||
|
||||
# 对齐长度(取最小公共频段)
|
||||
min_len = min(len(idx1), len(idx2))
|
||||
mag1_band = mag1[idx1[:min_len]]
|
||||
mag2_band = mag2[idx2[:min_len]]
|
||||
|
||||
# 计算余弦相似度
|
||||
dot_product = dot(mag1_band, mag2_band)
|
||||
norm1 = linalg.norm(mag1_band)
|
||||
norm2 = linalg.norm(mag2_band)
|
||||
|
||||
if norm1 == 0 or norm2 == 0:
|
||||
similarity = 0.0 # 避免除以零
|
||||
else:
|
||||
similarity = dot_product / (norm1 * norm2)
|
||||
|
||||
return similarity
|
||||
|
||||
|
||||
def get_bandpass_bcgsignal(
|
||||
bcg_signal: ndarray,
|
||||
tho_signal: ndarray,
|
||||
bcg_sample_rate: int,
|
||||
tho_sample_rate: int,
|
||||
use_custom_band: bool = False,
|
||||
low_cutoff: float = 0.1,
|
||||
high_cutoff: float = 1.0
|
||||
):
|
||||
"""
|
||||
绘制带通滤波后的BCG信号和原始THO信号对比图
|
||||
|
||||
Args:
|
||||
bcg_signal: 原始BCG信号数组
|
||||
tho_signal: 原始THO信号数组
|
||||
bcg_sample_rate: BCG信号采样率(Hz)
|
||||
tho_sample_rate: THO信号采样率(Hz)
|
||||
use_custom_band: 是否使用自定义频带 (默认自动检测)
|
||||
low_cutoff: 自定义低截止频率(Hz)
|
||||
high_cutoff: 自定义高截止频率(Hz)
|
||||
|
||||
Returns:
|
||||
filtered_bcg :带通滤波后的BCG信号(BDR信号)
|
||||
|
||||
"""
|
||||
# 参数校验
|
||||
if len(bcg_signal) == 0 or len(tho_signal) == 0:
|
||||
raise ValueError("输入信号不能为空数组")
|
||||
if low_cutoff >= high_cutoff:
|
||||
raise ValueError("截止频率范围不合法")
|
||||
|
||||
# 频谱分析
|
||||
tho_spectrum, tho_freq = fft1(tho_signal, tho_sample_rate)
|
||||
bcg_spectrum, bcg_freq = fft1(bcg_signal, bcg_sample_rate)
|
||||
|
||||
# 确定通带范围
|
||||
if use_custom_band:
|
||||
band_low = low_cutoff
|
||||
band_high = high_cutoff
|
||||
else:
|
||||
peak_freq = tho_freq[argmax(tho_spectrum)]
|
||||
band_low, band_high = detect_peak_bottoms(
|
||||
frequencies=bcg_freq,
|
||||
spectrum=bcg_spectrum,
|
||||
peak_idx=peak_freq,
|
||||
left_bound=max(peak_freq - 0.2, 0.1),
|
||||
right_bound=min(peak_freq + 0.2, 1.0)
|
||||
)
|
||||
|
||||
# 带通滤波
|
||||
filtered_bcg = bpf(
|
||||
bcg_signal,
|
||||
bcg_sample_rate,
|
||||
band_low,
|
||||
band_high
|
||||
)
|
||||
|
||||
return filtered_bcg, band_low, band_high, bcg_spectrum, bcg_freq, tho_spectrum, tho_freq
|
||||
|
||||
36
run.py
Normal file
36
run.py
Normal file
@ -0,0 +1,36 @@
|
||||
from logging import getLogger, NOTSET, FileHandler, Formatter, StreamHandler, info
|
||||
from pathlib import Path
|
||||
from sys import argv
|
||||
from time import strftime, localtime, time
|
||||
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
from func.Module_mainwindow import MainWindow
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 设置日志
|
||||
logger = getLogger()
|
||||
logger.setLevel(NOTSET)
|
||||
realtime = strftime('%Y%m%d', localtime(time()))
|
||||
if not Path("logs").exists():
|
||||
Path("logs").mkdir(exist_ok=True)
|
||||
fh = FileHandler(Path("logs") / (realtime + ".log"), mode='a')
|
||||
fh.setLevel(NOTSET)
|
||||
fh.setFormatter(Formatter("%(asctime)s: %(message)s"))
|
||||
logger.addHandler(fh)
|
||||
|
||||
ch = StreamHandler()
|
||||
ch.setLevel(NOTSET)
|
||||
ch.setFormatter(Formatter("%(asctime)s: %(message)s"))
|
||||
logger.addHandler(ch)
|
||||
getLogger('matplotlib.font_manager').disabled = True
|
||||
info("程序启动")
|
||||
|
||||
app = QApplication(argv)
|
||||
app.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
|
||||
app.styleHints().setColorScheme(Qt.ColorScheme.Light) # 强制使用浅色模式
|
||||
mainWindow = MainWindow()
|
||||
mainWindow.show()
|
||||
exit(app.exec())
|
||||
322
ui/MainWindow/MainWindow_detect_Jpeak.py
Normal file
322
ui/MainWindow/MainWindow_detect_Jpeak.py
Normal file
@ -0,0 +1,322 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'MainWindow_detect_Jpeak.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.8.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
|
||||
QCursor, QFont, QFontDatabase, QGradient,
|
||||
QIcon, QImage, QKeySequence, QLinearGradient,
|
||||
QPainter, QPalette, QPixmap, QRadialGradient,
|
||||
QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QDoubleSpinBox,
|
||||
QGridLayout, QGroupBox, QHBoxLayout, QLabel,
|
||||
QMainWindow, QPushButton, QSizePolicy, QSpacerItem,
|
||||
QSpinBox, QStatusBar, QTextBrowser, QVBoxLayout,
|
||||
QWidget)
|
||||
|
||||
class Ui_MainWindow_detect_Jpeak(object):
|
||||
def setupUi(self, MainWindow_detect_Jpeak):
|
||||
if not MainWindow_detect_Jpeak.objectName():
|
||||
MainWindow_detect_Jpeak.setObjectName(u"MainWindow_detect_Jpeak")
|
||||
MainWindow_detect_Jpeak.setEnabled(True)
|
||||
MainWindow_detect_Jpeak.resize(1920, 1080)
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Ignored, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(MainWindow_detect_Jpeak.sizePolicy().hasHeightForWidth())
|
||||
MainWindow_detect_Jpeak.setSizePolicy(sizePolicy)
|
||||
font = QFont()
|
||||
font.setPointSize(12)
|
||||
MainWindow_detect_Jpeak.setFont(font)
|
||||
self.action_selectPath = QAction(MainWindow_detect_Jpeak)
|
||||
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_detect_Jpeak)
|
||||
self.action.setObjectName(u"action")
|
||||
self.action.setFont(font1)
|
||||
self.centralwidget = QWidget(MainWindow_detect_Jpeak)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.gridLayout = QGridLayout(self.centralwidget)
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
self.groupBox_canvas = QGroupBox(self.centralwidget)
|
||||
self.groupBox_canvas.setObjectName(u"groupBox_canvas")
|
||||
self.verticalLayout_7 = QVBoxLayout(self.groupBox_canvas)
|
||||
self.verticalLayout_7.setObjectName(u"verticalLayout_7")
|
||||
self.verticalLayout_canvas = QVBoxLayout()
|
||||
self.verticalLayout_canvas.setObjectName(u"verticalLayout_canvas")
|
||||
|
||||
self.verticalLayout_7.addLayout(self.verticalLayout_canvas)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox_canvas, 0, 1, 1, 1)
|
||||
|
||||
self.groupBox_left = QGroupBox(self.centralwidget)
|
||||
self.groupBox_left.setObjectName(u"groupBox_left")
|
||||
font2 = QFont()
|
||||
font2.setPointSize(10)
|
||||
self.groupBox_left.setFont(font2)
|
||||
self.verticalLayout = QVBoxLayout(self.groupBox_left)
|
||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
||||
self.horizontalLayout_4 = QHBoxLayout()
|
||||
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
|
||||
self.pushButton_input_setting = QPushButton(self.groupBox_left)
|
||||
self.pushButton_input_setting.setObjectName(u"pushButton_input_setting")
|
||||
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
|
||||
sizePolicy1.setHorizontalStretch(0)
|
||||
sizePolicy1.setVerticalStretch(0)
|
||||
sizePolicy1.setHeightForWidth(self.pushButton_input_setting.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_input_setting.setSizePolicy(sizePolicy1)
|
||||
self.pushButton_input_setting.setFont(font)
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.pushButton_input_setting)
|
||||
|
||||
self.pushButton_input = QPushButton(self.groupBox_left)
|
||||
self.pushButton_input.setObjectName(u"pushButton_input")
|
||||
sizePolicy1.setHeightForWidth(self.pushButton_input.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_input.setSizePolicy(sizePolicy1)
|
||||
self.pushButton_input.setFont(font)
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.pushButton_input)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
||||
|
||||
self.groupBox_args = QGroupBox(self.groupBox_left)
|
||||
self.groupBox_args.setObjectName(u"groupBox_args")
|
||||
self.verticalLayout_5 = QVBoxLayout(self.groupBox_args)
|
||||
self.verticalLayout_5.setObjectName(u"verticalLayout_5")
|
||||
self.groupBox_2 = QGroupBox(self.groupBox_args)
|
||||
self.groupBox_2.setObjectName(u"groupBox_2")
|
||||
self.horizontalLayout_5 = QHBoxLayout(self.groupBox_2)
|
||||
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
|
||||
self.label = QLabel(self.groupBox_2)
|
||||
self.label.setObjectName(u"label")
|
||||
self.label.setFont(font)
|
||||
|
||||
self.horizontalLayout_5.addWidget(self.label)
|
||||
|
||||
self.doubleSpinBox_bandPassLow = QDoubleSpinBox(self.groupBox_2)
|
||||
self.doubleSpinBox_bandPassLow.setObjectName(u"doubleSpinBox_bandPassLow")
|
||||
self.doubleSpinBox_bandPassLow.setFont(font)
|
||||
self.doubleSpinBox_bandPassLow.setMaximum(100.000000000000000)
|
||||
|
||||
self.horizontalLayout_5.addWidget(self.doubleSpinBox_bandPassLow)
|
||||
|
||||
self.label_5 = QLabel(self.groupBox_2)
|
||||
self.label_5.setObjectName(u"label_5")
|
||||
self.label_5.setFont(font)
|
||||
self.label_5.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.horizontalLayout_5.addWidget(self.label_5)
|
||||
|
||||
self.doubleSpinBox_bandPassHigh = QDoubleSpinBox(self.groupBox_2)
|
||||
self.doubleSpinBox_bandPassHigh.setObjectName(u"doubleSpinBox_bandPassHigh")
|
||||
self.doubleSpinBox_bandPassHigh.setFont(font)
|
||||
self.doubleSpinBox_bandPassHigh.setMaximum(100.000000000000000)
|
||||
|
||||
self.horizontalLayout_5.addWidget(self.doubleSpinBox_bandPassHigh)
|
||||
|
||||
|
||||
self.verticalLayout_5.addWidget(self.groupBox_2)
|
||||
|
||||
self.horizontalLayout = QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.label_2 = QLabel(self.groupBox_args)
|
||||
self.label_2.setObjectName(u"label_2")
|
||||
self.label_2.setFont(font)
|
||||
self.label_2.setAlignment(Qt.AlignmentFlag.AlignLeading|Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter)
|
||||
|
||||
self.horizontalLayout.addWidget(self.label_2)
|
||||
|
||||
self.spinBox_peaksValue = QSpinBox(self.groupBox_args)
|
||||
self.spinBox_peaksValue.setObjectName(u"spinBox_peaksValue")
|
||||
self.spinBox_peaksValue.setFont(font)
|
||||
self.spinBox_peaksValue.setMinimum(1)
|
||||
self.spinBox_peaksValue.setMaximum(10000)
|
||||
|
||||
self.horizontalLayout.addWidget(self.spinBox_peaksValue)
|
||||
|
||||
self.horizontalLayout.setStretch(0, 1)
|
||||
self.horizontalLayout.setStretch(1, 1)
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout)
|
||||
|
||||
self.horizontalLayout_6 = QHBoxLayout()
|
||||
self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
|
||||
self.label_6 = QLabel(self.groupBox_args)
|
||||
self.label_6.setObjectName(u"label_6")
|
||||
self.label_6.setFont(font)
|
||||
|
||||
self.horizontalLayout_6.addWidget(self.label_6)
|
||||
|
||||
self.doubleSpinBox_ampValue = QDoubleSpinBox(self.groupBox_args)
|
||||
self.doubleSpinBox_ampValue.setObjectName(u"doubleSpinBox_ampValue")
|
||||
self.doubleSpinBox_ampValue.setFont(font)
|
||||
self.doubleSpinBox_ampValue.setMaximum(10000.000000000000000)
|
||||
|
||||
self.horizontalLayout_6.addWidget(self.doubleSpinBox_ampValue)
|
||||
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_6)
|
||||
|
||||
self.horizontalLayout_2 = QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
||||
self.label_3 = QLabel(self.groupBox_args)
|
||||
self.label_3.setObjectName(u"label_3")
|
||||
self.label_3.setFont(font)
|
||||
self.label_3.setAlignment(Qt.AlignmentFlag.AlignLeading|Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.label_3)
|
||||
|
||||
self.spinBox_intervalLow = QSpinBox(self.groupBox_args)
|
||||
self.spinBox_intervalLow.setObjectName(u"spinBox_intervalLow")
|
||||
self.spinBox_intervalLow.setFont(font)
|
||||
self.spinBox_intervalLow.setMinimum(1)
|
||||
self.spinBox_intervalLow.setMaximum(1000)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.spinBox_intervalLow)
|
||||
|
||||
self.label_4 = QLabel(self.groupBox_args)
|
||||
self.label_4.setObjectName(u"label_4")
|
||||
self.label_4.setFont(font)
|
||||
self.label_4.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.label_4)
|
||||
|
||||
self.spinBox_intervalHigh = QSpinBox(self.groupBox_args)
|
||||
self.spinBox_intervalHigh.setObjectName(u"spinBox_intervalHigh")
|
||||
self.spinBox_intervalHigh.setFont(font)
|
||||
self.spinBox_intervalHigh.setMinimum(1)
|
||||
self.spinBox_intervalHigh.setMaximum(1000)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.spinBox_intervalHigh)
|
||||
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_2)
|
||||
|
||||
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.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.comboBox_model = QComboBox(self.groupBox_3)
|
||||
self.comboBox_model.setObjectName(u"comboBox_model")
|
||||
self.comboBox_model.setFont(font)
|
||||
|
||||
self.verticalLayout_2.addWidget(self.comboBox_model)
|
||||
|
||||
|
||||
self.verticalLayout_5.addWidget(self.groupBox_3)
|
||||
|
||||
self.verticalLayout_5.setStretch(0, 1)
|
||||
self.verticalLayout_5.setStretch(1, 1)
|
||||
self.verticalLayout_5.setStretch(2, 1)
|
||||
self.verticalLayout_5.setStretch(3, 1)
|
||||
self.verticalLayout_5.setStretch(4, 3)
|
||||
|
||||
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)
|
||||
self.pushButton_view.setObjectName(u"pushButton_view")
|
||||
sizePolicy1.setHeightForWidth(self.pushButton_view.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_view.setSizePolicy(sizePolicy1)
|
||||
self.pushButton_view.setFont(font)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.pushButton_view)
|
||||
|
||||
self.pushButton_save = QPushButton(self.groupBox_left)
|
||||
self.pushButton_save.setObjectName(u"pushButton_save")
|
||||
sizePolicy1.setHeightForWidth(self.pushButton_save.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_save.setSizePolicy(sizePolicy1)
|
||||
self.pushButton_save.setFont(font)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.pushButton_save)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
||||
|
||||
self.groupBox = QGroupBox(self.groupBox_left)
|
||||
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.verticalLayout.addWidget(self.groupBox)
|
||||
|
||||
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.gridLayout.addWidget(self.groupBox_left, 0, 0, 1, 1)
|
||||
|
||||
self.gridLayout.setColumnStretch(0, 2)
|
||||
self.gridLayout.setColumnStretch(1, 8)
|
||||
MainWindow_detect_Jpeak.setCentralWidget(self.centralwidget)
|
||||
self.statusBar = QStatusBar(MainWindow_detect_Jpeak)
|
||||
self.statusBar.setObjectName(u"statusBar")
|
||||
MainWindow_detect_Jpeak.setStatusBar(self.statusBar)
|
||||
|
||||
self.retranslateUi(MainWindow_detect_Jpeak)
|
||||
|
||||
QMetaObject.connectSlotsByName(MainWindow_detect_Jpeak)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, MainWindow_detect_Jpeak):
|
||||
MainWindow_detect_Jpeak.setWindowTitle(QCoreApplication.translate("MainWindow_detect_Jpeak", u"BCG\u7684J\u5cf0\u7b97\u6cd5\u5b9a\u4f4d", None))
|
||||
self.action_selectPath.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u6570\u636e\u8def\u5f84\u9009\u62e9", None))
|
||||
self.action.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u52a0\u8f7d\u5b58\u6863", None))
|
||||
self.groupBox_canvas.setTitle(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u7ed8\u56fe\u533a", None))
|
||||
self.groupBox_left.setTitle(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u9884\u5904\u7406", None))
|
||||
self.pushButton_input_setting.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u5bfc\u5165\u8bbe\u7f6e", None))
|
||||
self.pushButton_input.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u5f00\u59cb\u5bfc\u5165", None))
|
||||
self.groupBox_args.setTitle(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u53c2\u6570\u8f93\u5165", None))
|
||||
self.groupBox_2.setTitle(QCoreApplication.translate("MainWindow_detect_Jpeak", u"BCG\u7684\u5e26\u901a\u6ee4\u6ce2", None))
|
||||
self.label.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u622a\u6b62\u9891\u7387(Hz)\uff1a", None))
|
||||
self.label_5.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"~", None))
|
||||
self.label_2.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u5bfb\u5cf0\u9608\u503c(\u4e2a)", None))
|
||||
self.label_6.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u4fe1\u53f7\u5e45\u503c\u8c03\u6574\u53c2\u6570", None))
|
||||
self.label_3.setText(QCoreApplication.translate("MainWindow_detect_Jpeak", u"\u95f4\u671f\u4e0b\u4e0a\u9650\u9608\u503c", None))
|
||||
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.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))
|
||||
# retranslateUi
|
||||
|
||||
431
ui/MainWindow/MainWindow_detect_Jpeak.ui
Normal file
431
ui/MainWindow/MainWindow_detect_Jpeak.ui
Normal file
@ -0,0 +1,431 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow_detect_Jpeak</class>
|
||||
<widget class="QMainWindow" name="MainWindow_detect_Jpeak">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>BCG的J峰算法定位</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="2,8">
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_canvas">
|
||||
<property name="title">
|
||||
<string>绘图区</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_canvas"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_left">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>预处理</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,7,4,1,5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_input_setting">
|
||||
<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="text">
|
||||
<string>导入设置</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_input">
|
||||
<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="text">
|
||||
<string>开始导入</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_args">
|
||||
<property name="title">
|
||||
<string>参数输入</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="1,1,1,1,3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>BCG的带通滤波</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>截止频率(Hz):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_bandPassLow">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>100.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<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>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_bandPassHigh">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>100.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>寻峰阈值(个)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_peaksValue">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>信号幅值调整参数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_ampValue">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10000.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>间期下上限阈值</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_intervalLow">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<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>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_intervalHigh">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>模型设置</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_useCPU">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>强制使用CPU</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<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>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_model">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</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_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_view">
|
||||
<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="text">
|
||||
<string>查看结果</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_save">
|
||||
<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="text">
|
||||
<string>保存结果</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
<action name="action_selectPath">
|
||||
<property name="text">
|
||||
<string>数据路径选择</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>黑体</family>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action">
|
||||
<property name="text">
|
||||
<string>加载存档</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>黑体</family>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
234
ui/MainWindow/MainWindow_menu.py
Normal file
234
ui/MainWindow/MainWindow_menu.py
Normal file
@ -0,0 +1,234 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'MainWindow_menu.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.8.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QFont, QFontDatabase, QGradient, QIcon,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QComboBox, QGridLayout, QHBoxLayout,
|
||||
QLabel, QMainWindow, QPlainTextEdit, QPushButton,
|
||||
QSizePolicy, QSpacerItem, QStatusBar, QVBoxLayout,
|
||||
QWidget)
|
||||
|
||||
class Ui_Signal_Label(object):
|
||||
def setupUi(self, Signal_Label):
|
||||
if not Signal_Label.objectName():
|
||||
Signal_Label.setObjectName(u"Signal_Label")
|
||||
Signal_Label.resize(675, 1008)
|
||||
self.centralwidget = QWidget(Signal_Label)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.gridLayout = QGridLayout(self.centralwidget)
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
self.verticalLayout = QVBoxLayout()
|
||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
||||
self.horizontalLayout = QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.verticalLayout_3 = QVBoxLayout()
|
||||
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
||||
self.label = QLabel(self.centralwidget)
|
||||
self.label.setObjectName(u"label")
|
||||
font = QFont()
|
||||
font.setPointSize(14)
|
||||
self.label.setFont(font)
|
||||
|
||||
self.verticalLayout_3.addWidget(self.label)
|
||||
|
||||
self.plainTextEdit_root_path = QPlainTextEdit(self.centralwidget)
|
||||
self.plainTextEdit_root_path.setObjectName(u"plainTextEdit_root_path")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.plainTextEdit_root_path)
|
||||
|
||||
|
||||
self.horizontalLayout.addLayout(self.verticalLayout_3)
|
||||
|
||||
self.verticalLayout_2 = QVBoxLayout()
|
||||
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
||||
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
|
||||
|
||||
self.verticalLayout_2.addItem(self.verticalSpacer)
|
||||
|
||||
self.comboBox_sampID = QComboBox(self.centralwidget)
|
||||
self.comboBox_sampID.setObjectName(u"comboBox_sampID")
|
||||
self.comboBox_sampID.setFont(font)
|
||||
|
||||
self.verticalLayout_2.addWidget(self.comboBox_sampID)
|
||||
|
||||
self.pushButton_open = QPushButton(self.centralwidget)
|
||||
self.pushButton_open.setObjectName(u"pushButton_open")
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.pushButton_open.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_open.setSizePolicy(sizePolicy)
|
||||
self.pushButton_open.setFont(font)
|
||||
|
||||
self.verticalLayout_2.addWidget(self.pushButton_open)
|
||||
|
||||
|
||||
self.horizontalLayout.addLayout(self.verticalLayout_2)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
|
||||
self.pushButton_2 = QPushButton(self.centralwidget)
|
||||
self.pushButton_2.setObjectName(u"pushButton_2")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_2.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_2.setSizePolicy(sizePolicy)
|
||||
self.pushButton_2.setFont(font)
|
||||
|
||||
self.verticalLayout.addWidget(self.pushButton_2)
|
||||
|
||||
self.horizontalLayout_2 = QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
||||
self.pushButton_preprocess_BCG = QPushButton(self.centralwidget)
|
||||
self.pushButton_preprocess_BCG.setObjectName(u"pushButton_preprocess_BCG")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_preprocess_BCG.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_preprocess_BCG.setSizePolicy(sizePolicy)
|
||||
self.pushButton_preprocess_BCG.setFont(font)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.pushButton_preprocess_BCG)
|
||||
|
||||
self.pushButton_preprocess_ECG = QPushButton(self.centralwidget)
|
||||
self.pushButton_preprocess_ECG.setObjectName(u"pushButton_preprocess_ECG")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_preprocess_ECG.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_preprocess_ECG.setSizePolicy(sizePolicy)
|
||||
self.pushButton_preprocess_ECG.setFont(font)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.pushButton_preprocess_ECG)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
||||
|
||||
self.horizontalLayout_3 = QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
||||
self.pushButton_detect_Jpeak = QPushButton(self.centralwidget)
|
||||
self.pushButton_detect_Jpeak.setObjectName(u"pushButton_detect_Jpeak")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_detect_Jpeak.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_detect_Jpeak.setSizePolicy(sizePolicy)
|
||||
self.pushButton_detect_Jpeak.setFont(font)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.pushButton_detect_Jpeak)
|
||||
|
||||
self.pushButton_detect_Rpeak = QPushButton(self.centralwidget)
|
||||
self.pushButton_detect_Rpeak.setObjectName(u"pushButton_detect_Rpeak")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_detect_Rpeak.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_detect_Rpeak.setSizePolicy(sizePolicy)
|
||||
self.pushButton_detect_Rpeak.setFont(font)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.pushButton_detect_Rpeak)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
||||
|
||||
self.horizontalLayout_6 = QHBoxLayout()
|
||||
self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
|
||||
self.pushButton_7 = QPushButton(self.centralwidget)
|
||||
self.pushButton_7.setObjectName(u"pushButton_7")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_7.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_7.setSizePolicy(sizePolicy)
|
||||
self.pushButton_7.setFont(font)
|
||||
|
||||
self.horizontalLayout_6.addWidget(self.pushButton_7)
|
||||
|
||||
self.pushButton_8 = QPushButton(self.centralwidget)
|
||||
self.pushButton_8.setObjectName(u"pushButton_8")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_8.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_8.setSizePolicy(sizePolicy)
|
||||
self.pushButton_8.setFont(font)
|
||||
|
||||
self.horizontalLayout_6.addWidget(self.pushButton_8)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_6)
|
||||
|
||||
self.pushButton_10 = QPushButton(self.centralwidget)
|
||||
self.pushButton_10.setObjectName(u"pushButton_10")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_10.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_10.setSizePolicy(sizePolicy)
|
||||
self.pushButton_10.setFont(font)
|
||||
|
||||
self.verticalLayout.addWidget(self.pushButton_10)
|
||||
|
||||
self.pushButton_9 = QPushButton(self.centralwidget)
|
||||
self.pushButton_9.setObjectName(u"pushButton_9")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_9.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_9.setSizePolicy(sizePolicy)
|
||||
self.pushButton_9.setFont(font)
|
||||
|
||||
self.verticalLayout.addWidget(self.pushButton_9)
|
||||
|
||||
self.pushButton_11 = QPushButton(self.centralwidget)
|
||||
self.pushButton_11.setObjectName(u"pushButton_11")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_11.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_11.setSizePolicy(sizePolicy)
|
||||
self.pushButton_11.setFont(font)
|
||||
|
||||
self.verticalLayout.addWidget(self.pushButton_11)
|
||||
|
||||
self.pushButton_12 = QPushButton(self.centralwidget)
|
||||
self.pushButton_12.setObjectName(u"pushButton_12")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_12.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_12.setSizePolicy(sizePolicy)
|
||||
self.pushButton_12.setFont(font)
|
||||
|
||||
self.verticalLayout.addWidget(self.pushButton_12)
|
||||
|
||||
self.pushButton_13 = QPushButton(self.centralwidget)
|
||||
self.pushButton_13.setObjectName(u"pushButton_13")
|
||||
sizePolicy.setHeightForWidth(self.pushButton_13.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_13.setSizePolicy(sizePolicy)
|
||||
self.pushButton_13.setFont(font)
|
||||
|
||||
self.verticalLayout.addWidget(self.pushButton_13)
|
||||
|
||||
self.verticalLayout.setStretch(0, 1)
|
||||
self.verticalLayout.setStretch(1, 1)
|
||||
self.verticalLayout.setStretch(2, 1)
|
||||
self.verticalLayout.setStretch(3, 1)
|
||||
self.verticalLayout.setStretch(4, 1)
|
||||
self.verticalLayout.setStretch(5, 1)
|
||||
self.verticalLayout.setStretch(6, 1)
|
||||
self.verticalLayout.setStretch(7, 1)
|
||||
self.verticalLayout.setStretch(8, 1)
|
||||
self.verticalLayout.setStretch(9, 1)
|
||||
|
||||
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
|
||||
|
||||
Signal_Label.setCentralWidget(self.centralwidget)
|
||||
self.statusbar = QStatusBar(Signal_Label)
|
||||
self.statusbar.setObjectName(u"statusbar")
|
||||
Signal_Label.setStatusBar(self.statusbar)
|
||||
|
||||
self.retranslateUi(Signal_Label)
|
||||
|
||||
QMetaObject.connectSlotsByName(Signal_Label)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, Signal_Label):
|
||||
Signal_Label.setWindowTitle(QCoreApplication.translate("Signal_Label", u"Signal_Label", None))
|
||||
self.label.setText(QCoreApplication.translate("Signal_Label", u"\u6570\u636e\u6839\u76ee\u5f55\uff1a", None))
|
||||
self.pushButton_open.setText(QCoreApplication.translate("Signal_Label", u"\u6253\u5f00", None))
|
||||
self.pushButton_2.setText(QCoreApplication.translate("Signal_Label", u"\u6570\u636e\u7c97\u540c\u6b65", None))
|
||||
self.pushButton_preprocess_BCG.setText(QCoreApplication.translate("Signal_Label", u"BCG\u7684\u9884\u5904\u7406", None))
|
||||
self.pushButton_preprocess_ECG.setText(QCoreApplication.translate("Signal_Label", u"ECG\u7684\u9884\u5904\u7406", None))
|
||||
self.pushButton_detect_Jpeak.setText(QCoreApplication.translate("Signal_Label", u"BCG\u7684J\u5cf0\u7b97\u6cd5\u5b9a\u4f4d", None))
|
||||
self.pushButton_detect_Rpeak.setText(QCoreApplication.translate("Signal_Label", u"ECG\u7684R\u5cf0\u7b97\u6cd5\u5b9a\u4f4d", None))
|
||||
self.pushButton_7.setText(QCoreApplication.translate("Signal_Label", u"BCG\u7684J\u5cf0\u4eba\u5de5\u7ea0\u6b63", None))
|
||||
self.pushButton_8.setText(QCoreApplication.translate("Signal_Label", u"ECG\u7684R\u5cf0\u4eba\u5de5\u7ea0\u6b63", None))
|
||||
self.pushButton_10.setText(QCoreApplication.translate("Signal_Label", u"\u6570\u636e\u7cbe\u540c\u6b65", None))
|
||||
self.pushButton_9.setText(QCoreApplication.translate("Signal_Label", u"\u4f53\u52a8\u6807\u6ce8", None))
|
||||
self.pushButton_11.setText(QCoreApplication.translate("Signal_Label", u"BCG\u7684\u8d28\u91cf\u6807\u6ce8", None))
|
||||
self.pushButton_12.setText(QCoreApplication.translate("Signal_Label", u"\u547c\u5438\u53ef\u7528\u6027\u53ca\u95f4\u671f\u6807\u6ce8", None))
|
||||
self.pushButton_13.setText(QCoreApplication.translate("Signal_Label", u"\u7761\u7720\u547c\u5438\u6682\u505c\u4e8b\u4ef6\u6807\u6ce8", None))
|
||||
# retranslateUi
|
||||
|
||||
323
ui/MainWindow/MainWindow_menu.ui
Normal file
323
ui/MainWindow/MainWindow_menu.ui
Normal file
@ -0,0 +1,323 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Signal_Label</class>
|
||||
<widget class="QMainWindow" name="Signal_Label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>675</width>
|
||||
<height>1008</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Signal_Label</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,1,1,1,1,1,1,1,1,1">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>数据根目录:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit_root_path"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<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>
|
||||
<widget class="QComboBox" name="comboBox_sampID">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_open">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>打开</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>数据粗同步</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_preprocess_BCG">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>BCG的预处理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_preprocess_ECG">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ECG的预处理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_detect_Jpeak">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>BCG的J峰算法定位</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_detect_Rpeak">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ECG的R峰算法定位</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>BCG的J峰人工纠正</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ECG的R峰人工纠正</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_10">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>数据精同步</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_9">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>体动标注</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_11">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>BCG的质量标注</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_12">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>呼吸可用性及间期标注</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_13">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>睡眠呼吸暂停事件标注</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
238
ui/MainWindow/MainWindow_preprocess.py
Normal file
238
ui/MainWindow/MainWindow_preprocess.py
Normal file
@ -0,0 +1,238 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'MainWindow_preprocess.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.8.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
|
||||
QCursor, QFont, QFontDatabase, QGradient,
|
||||
QIcon, QImage, QKeySequence, QLinearGradient,
|
||||
QPainter, QPalette, QPixmap, QRadialGradient,
|
||||
QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QDoubleSpinBox, QGridLayout, QGroupBox,
|
||||
QHBoxLayout, QLabel, QMainWindow, QPushButton,
|
||||
QSizePolicy, QSpacerItem, QSpinBox, QStatusBar,
|
||||
QTextBrowser, QVBoxLayout, QWidget)
|
||||
|
||||
class Ui_MainWindow_preprocess(object):
|
||||
def setupUi(self, MainWindow_preprocess):
|
||||
if not MainWindow_preprocess.objectName():
|
||||
MainWindow_preprocess.setObjectName(u"MainWindow_preprocess")
|
||||
MainWindow_preprocess.setEnabled(True)
|
||||
MainWindow_preprocess.resize(1920, 1080)
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Ignored, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(MainWindow_preprocess.sizePolicy().hasHeightForWidth())
|
||||
MainWindow_preprocess.setSizePolicy(sizePolicy)
|
||||
font = QFont()
|
||||
font.setPointSize(12)
|
||||
MainWindow_preprocess.setFont(font)
|
||||
self.action_selectPath = QAction(MainWindow_preprocess)
|
||||
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_preprocess)
|
||||
self.action.setObjectName(u"action")
|
||||
self.action.setFont(font1)
|
||||
self.centralwidget = QWidget(MainWindow_preprocess)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.gridLayout = QGridLayout(self.centralwidget)
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
self.groupBox_canvas = QGroupBox(self.centralwidget)
|
||||
self.groupBox_canvas.setObjectName(u"groupBox_canvas")
|
||||
self.verticalLayout_7 = QVBoxLayout(self.groupBox_canvas)
|
||||
self.verticalLayout_7.setObjectName(u"verticalLayout_7")
|
||||
self.verticalLayout_canvas = QVBoxLayout()
|
||||
self.verticalLayout_canvas.setObjectName(u"verticalLayout_canvas")
|
||||
|
||||
self.verticalLayout_7.addLayout(self.verticalLayout_canvas)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox_canvas, 0, 1, 1, 1)
|
||||
|
||||
self.groupBox_left = QGroupBox(self.centralwidget)
|
||||
self.groupBox_left.setObjectName(u"groupBox_left")
|
||||
font2 = QFont()
|
||||
font2.setPointSize(10)
|
||||
self.groupBox_left.setFont(font2)
|
||||
self.verticalLayout = QVBoxLayout(self.groupBox_left)
|
||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
||||
self.horizontalLayout_4 = QHBoxLayout()
|
||||
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
|
||||
self.pushButton_input_setting = QPushButton(self.groupBox_left)
|
||||
self.pushButton_input_setting.setObjectName(u"pushButton_input_setting")
|
||||
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
|
||||
sizePolicy1.setHorizontalStretch(0)
|
||||
sizePolicy1.setVerticalStretch(0)
|
||||
sizePolicy1.setHeightForWidth(self.pushButton_input_setting.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_input_setting.setSizePolicy(sizePolicy1)
|
||||
self.pushButton_input_setting.setFont(font)
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.pushButton_input_setting)
|
||||
|
||||
self.pushButton_input = QPushButton(self.groupBox_left)
|
||||
self.pushButton_input.setObjectName(u"pushButton_input")
|
||||
sizePolicy1.setHeightForWidth(self.pushButton_input.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_input.setSizePolicy(sizePolicy1)
|
||||
self.pushButton_input.setFont(font)
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.pushButton_input)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
||||
|
||||
self.groupBox_args = QGroupBox(self.groupBox_left)
|
||||
self.groupBox_args.setObjectName(u"groupBox_args")
|
||||
self.verticalLayout_5 = QVBoxLayout(self.groupBox_args)
|
||||
self.verticalLayout_5.setObjectName(u"verticalLayout_5")
|
||||
self.label_mode = QLabel(self.groupBox_args)
|
||||
self.label_mode.setObjectName(u"label_mode")
|
||||
font3 = QFont()
|
||||
font3.setPointSize(14)
|
||||
self.label_mode.setFont(font3)
|
||||
self.label_mode.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.verticalLayout_5.addWidget(self.label_mode)
|
||||
|
||||
self.horizontalLayout = QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.label_2 = QLabel(self.groupBox_args)
|
||||
self.label_2.setObjectName(u"label_2")
|
||||
self.label_2.setFont(font)
|
||||
self.label_2.setAlignment(Qt.AlignmentFlag.AlignLeading|Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter)
|
||||
|
||||
self.horizontalLayout.addWidget(self.label_2)
|
||||
|
||||
self.spinBox_bandPassOrder = QSpinBox(self.groupBox_args)
|
||||
self.spinBox_bandPassOrder.setObjectName(u"spinBox_bandPassOrder")
|
||||
self.spinBox_bandPassOrder.setFont(font)
|
||||
self.spinBox_bandPassOrder.setMaximum(10)
|
||||
|
||||
self.horizontalLayout.addWidget(self.spinBox_bandPassOrder)
|
||||
|
||||
self.horizontalLayout.setStretch(0, 2)
|
||||
self.horizontalLayout.setStretch(1, 8)
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout)
|
||||
|
||||
self.horizontalLayout_2 = QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
||||
self.label_3 = QLabel(self.groupBox_args)
|
||||
self.label_3.setObjectName(u"label_3")
|
||||
self.label_3.setFont(font)
|
||||
self.label_3.setAlignment(Qt.AlignmentFlag.AlignLeading|Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.label_3)
|
||||
|
||||
self.doubleSpinBox_bandPassLow = QDoubleSpinBox(self.groupBox_args)
|
||||
self.doubleSpinBox_bandPassLow.setObjectName(u"doubleSpinBox_bandPassLow")
|
||||
self.doubleSpinBox_bandPassLow.setFont(font)
|
||||
self.doubleSpinBox_bandPassLow.setMaximum(100.000000000000000)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.doubleSpinBox_bandPassLow)
|
||||
|
||||
self.label_4 = QLabel(self.groupBox_args)
|
||||
self.label_4.setObjectName(u"label_4")
|
||||
self.label_4.setFont(font)
|
||||
self.label_4.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.label_4)
|
||||
|
||||
self.doubleSpinBox_bandPassHigh = QDoubleSpinBox(self.groupBox_args)
|
||||
self.doubleSpinBox_bandPassHigh.setObjectName(u"doubleSpinBox_bandPassHigh")
|
||||
self.doubleSpinBox_bandPassHigh.setFont(font)
|
||||
self.doubleSpinBox_bandPassHigh.setMaximum(100.000000000000000)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.doubleSpinBox_bandPassHigh)
|
||||
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_2)
|
||||
|
||||
|
||||
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)
|
||||
self.pushButton_view.setObjectName(u"pushButton_view")
|
||||
sizePolicy1.setHeightForWidth(self.pushButton_view.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_view.setSizePolicy(sizePolicy1)
|
||||
self.pushButton_view.setFont(font)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.pushButton_view)
|
||||
|
||||
self.pushButton_save = QPushButton(self.groupBox_left)
|
||||
self.pushButton_save.setObjectName(u"pushButton_save")
|
||||
sizePolicy1.setHeightForWidth(self.pushButton_save.sizePolicy().hasHeightForWidth())
|
||||
self.pushButton_save.setSizePolicy(sizePolicy1)
|
||||
self.pushButton_save.setFont(font)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.pushButton_save)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
||||
|
||||
self.groupBox = QGroupBox(self.groupBox_left)
|
||||
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.verticalLayout.addWidget(self.groupBox)
|
||||
|
||||
self.verticalLayout.setStretch(0, 1)
|
||||
self.verticalLayout.setStretch(1, 3)
|
||||
self.verticalLayout.setStretch(2, 7)
|
||||
self.verticalLayout.setStretch(3, 1)
|
||||
self.verticalLayout.setStretch(4, 5)
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox_left, 0, 0, 1, 1)
|
||||
|
||||
self.gridLayout.setColumnStretch(0, 2)
|
||||
self.gridLayout.setColumnStretch(1, 8)
|
||||
MainWindow_preprocess.setCentralWidget(self.centralwidget)
|
||||
self.statusBar = QStatusBar(MainWindow_preprocess)
|
||||
self.statusBar.setObjectName(u"statusBar")
|
||||
MainWindow_preprocess.setStatusBar(self.statusBar)
|
||||
|
||||
self.retranslateUi(MainWindow_preprocess)
|
||||
|
||||
QMetaObject.connectSlotsByName(MainWindow_preprocess)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, MainWindow_preprocess):
|
||||
MainWindow_preprocess.setWindowTitle(QCoreApplication.translate("MainWindow_preprocess", u"\u9884\u5904\u7406", None))
|
||||
self.action_selectPath.setText(QCoreApplication.translate("MainWindow_preprocess", u"\u6570\u636e\u8def\u5f84\u9009\u62e9", None))
|
||||
self.action.setText(QCoreApplication.translate("MainWindow_preprocess", u"\u52a0\u8f7d\u5b58\u6863", None))
|
||||
self.groupBox_canvas.setTitle(QCoreApplication.translate("MainWindow_preprocess", u"\u7ed8\u56fe\u533a", None))
|
||||
self.groupBox_left.setTitle(QCoreApplication.translate("MainWindow_preprocess", u"\u9884\u5904\u7406", None))
|
||||
self.pushButton_input_setting.setText(QCoreApplication.translate("MainWindow_preprocess", u"\u5bfc\u5165\u8bbe\u7f6e", None))
|
||||
self.pushButton_input.setText(QCoreApplication.translate("MainWindow_preprocess", u"\u5f00\u59cb\u5bfc\u5165", None))
|
||||
self.groupBox_args.setTitle(QCoreApplication.translate("MainWindow_preprocess", u"\u53c2\u6570\u8f93\u5165", None))
|
||||
self.label_mode.setText(QCoreApplication.translate("MainWindow_preprocess", u"\u5904\u7406\u7684\u4fe1\u53f7\u7c7b\u578b", None))
|
||||
self.label_2.setText(QCoreApplication.translate("MainWindow_preprocess", u"\u9636\u6570", None))
|
||||
self.label_3.setText(QCoreApplication.translate("MainWindow_preprocess", u"\u622a\u6b62\u9891\u7387(Hz)\uff1a", None))
|
||||
self.label_4.setText(QCoreApplication.translate("MainWindow_preprocess", u"~", None))
|
||||
self.pushButton_view.setText(QCoreApplication.translate("MainWindow_preprocess", u"\u67e5\u770b\u7ed3\u679c", None))
|
||||
self.pushButton_save.setText(QCoreApplication.translate("MainWindow_preprocess", u"\u4fdd\u5b58\u7ed3\u679c", None))
|
||||
self.groupBox.setTitle(QCoreApplication.translate("MainWindow_preprocess", u"\u65e5\u5fd7", None))
|
||||
# retranslateUi
|
||||
|
||||
304
ui/MainWindow/MainWindow_preprocess.ui
Normal file
304
ui/MainWindow/MainWindow_preprocess.ui
Normal file
@ -0,0 +1,304 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow_preprocess</class>
|
||||
<widget class="QMainWindow" name="MainWindow_preprocess">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>预处理</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="2,8">
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_canvas">
|
||||
<property name="title">
|
||||
<string>绘图区</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_canvas"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_left">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>预处理</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,3,7,1,5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_input_setting">
|
||||
<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="text">
|
||||
<string>导入设置</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_input">
|
||||
<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="text">
|
||||
<string>开始导入</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_args">
|
||||
<property name="title">
|
||||
<string>参数输入</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_mode">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>处理的信号类型</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="2,8">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>阶数</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_bandPassOrder">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>截止频率(Hz):</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_bandPassLow">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>100.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<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>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_bandPassHigh">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>100.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</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_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_view">
|
||||
<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="text">
|
||||
<string>查看结果</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_save">
|
||||
<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="text">
|
||||
<string>保存结果</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
<action name="action_selectPath">
|
||||
<property name="text">
|
||||
<string>数据路径选择</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>黑体</family>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action">
|
||||
<property name="text">
|
||||
<string>加载存档</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>黑体</family>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
133
ui/setting/detect_Jpeak_input_setting.py
Normal file
133
ui/setting/detect_Jpeak_input_setting.py
Normal file
@ -0,0 +1,133 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'detect_Jpeak_input_setting.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.8.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QFont, QFontDatabase, QGradient, QIcon,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QGridLayout, QGroupBox, QHBoxLayout,
|
||||
QLabel, QMainWindow, QPlainTextEdit, QPushButton,
|
||||
QSizePolicy, QSpinBox, QVBoxLayout, QWidget)
|
||||
|
||||
class Ui_MainWindow_detect_Jpeak_input_setting(object):
|
||||
def setupUi(self, MainWindow_detect_Jpeak_input_setting):
|
||||
if not MainWindow_detect_Jpeak_input_setting.objectName():
|
||||
MainWindow_detect_Jpeak_input_setting.setObjectName(u"MainWindow_detect_Jpeak_input_setting")
|
||||
MainWindow_detect_Jpeak_input_setting.resize(487, 417)
|
||||
self.centralwidget = QWidget(MainWindow_detect_Jpeak_input_setting)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.gridLayout = QGridLayout(self.centralwidget)
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
self.pushButton_cancel = QPushButton(self.centralwidget)
|
||||
self.pushButton_cancel.setObjectName(u"pushButton_cancel")
|
||||
font = QFont()
|
||||
font.setPointSize(12)
|
||||
self.pushButton_cancel.setFont(font)
|
||||
|
||||
self.gridLayout.addWidget(self.pushButton_cancel, 2, 3, 1, 1)
|
||||
|
||||
self.groupBox = QGroupBox(self.centralwidget)
|
||||
self.groupBox.setObjectName(u"groupBox")
|
||||
self.verticalLayout_2 = QVBoxLayout(self.groupBox)
|
||||
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
||||
self.groupBox_file_path_input = QGroupBox(self.groupBox)
|
||||
self.groupBox_file_path_input.setObjectName(u"groupBox_file_path_input")
|
||||
self.verticalLayout_3 = QVBoxLayout(self.groupBox_file_path_input)
|
||||
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
||||
self.horizontalLayout = QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.label = QLabel(self.groupBox_file_path_input)
|
||||
self.label.setObjectName(u"label")
|
||||
self.label.setFont(font)
|
||||
|
||||
self.horizontalLayout.addWidget(self.label)
|
||||
|
||||
self.spinBox_input_freq = QSpinBox(self.groupBox_file_path_input)
|
||||
self.spinBox_input_freq.setObjectName(u"spinBox_input_freq")
|
||||
self.spinBox_input_freq.setFont(font)
|
||||
self.spinBox_input_freq.setMinimum(1)
|
||||
self.spinBox_input_freq.setMaximum(1000000)
|
||||
|
||||
self.horizontalLayout.addWidget(self.spinBox_input_freq)
|
||||
|
||||
|
||||
self.verticalLayout_3.addLayout(self.horizontalLayout)
|
||||
|
||||
self.plainTextEdit_file_path_input = QPlainTextEdit(self.groupBox_file_path_input)
|
||||
self.plainTextEdit_file_path_input.setObjectName(u"plainTextEdit_file_path_input")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.plainTextEdit_file_path_input)
|
||||
|
||||
self.verticalLayout_3.setStretch(0, 1)
|
||||
self.verticalLayout_3.setStretch(1, 2)
|
||||
|
||||
self.verticalLayout_2.addWidget(self.groupBox_file_path_input)
|
||||
|
||||
self.groupBox_deepmodel_path = QGroupBox(self.groupBox)
|
||||
self.groupBox_deepmodel_path.setObjectName(u"groupBox_deepmodel_path")
|
||||
self.verticalLayout = QVBoxLayout(self.groupBox_deepmodel_path)
|
||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
||||
self.plainTextEdit_deepmodel_path = QPlainTextEdit(self.groupBox_deepmodel_path)
|
||||
self.plainTextEdit_deepmodel_path.setObjectName(u"plainTextEdit_deepmodel_path")
|
||||
|
||||
self.verticalLayout.addWidget(self.plainTextEdit_deepmodel_path)
|
||||
|
||||
|
||||
self.verticalLayout_2.addWidget(self.groupBox_deepmodel_path)
|
||||
|
||||
self.groupBox_file_path_save = QGroupBox(self.groupBox)
|
||||
self.groupBox_file_path_save.setObjectName(u"groupBox_file_path_save")
|
||||
self.verticalLayout_4 = QVBoxLayout(self.groupBox_file_path_save)
|
||||
self.verticalLayout_4.setObjectName(u"verticalLayout_4")
|
||||
self.plainTextEdit_file_path_save = QPlainTextEdit(self.groupBox_file_path_save)
|
||||
self.plainTextEdit_file_path_save.setObjectName(u"plainTextEdit_file_path_save")
|
||||
|
||||
self.verticalLayout_4.addWidget(self.plainTextEdit_file_path_save)
|
||||
|
||||
|
||||
self.verticalLayout_2.addWidget(self.groupBox_file_path_save)
|
||||
|
||||
self.verticalLayout_2.setStretch(0, 2)
|
||||
self.verticalLayout_2.setStretch(1, 1)
|
||||
self.verticalLayout_2.setStretch(2, 1)
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 4)
|
||||
|
||||
self.pushButton_confirm = QPushButton(self.centralwidget)
|
||||
self.pushButton_confirm.setObjectName(u"pushButton_confirm")
|
||||
self.pushButton_confirm.setFont(font)
|
||||
|
||||
self.gridLayout.addWidget(self.pushButton_confirm, 2, 2, 1, 1)
|
||||
|
||||
MainWindow_detect_Jpeak_input_setting.setCentralWidget(self.centralwidget)
|
||||
|
||||
self.retranslateUi(MainWindow_detect_Jpeak_input_setting)
|
||||
|
||||
QMetaObject.connectSlotsByName(MainWindow_detect_Jpeak_input_setting)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, MainWindow_detect_Jpeak_input_setting):
|
||||
MainWindow_detect_Jpeak_input_setting.setWindowTitle(QCoreApplication.translate("MainWindow_detect_Jpeak_input_setting", u"\u5bfc\u5165\u8bbe\u7f6e", None))
|
||||
self.pushButton_cancel.setText(QCoreApplication.translate("MainWindow_detect_Jpeak_input_setting", u"\u53d6\u6d88", None))
|
||||
self.groupBox.setTitle(QCoreApplication.translate("MainWindow_detect_Jpeak_input_setting", u"\u6587\u4ef6\u8def\u5f84", None))
|
||||
self.groupBox_file_path_input.setTitle(QCoreApplication.translate("MainWindow_detect_Jpeak_input_setting", u"\u6ee4\u6ce2\u540e\u7684BCG\u8def\u5f84", None))
|
||||
self.label.setText(QCoreApplication.translate("MainWindow_detect_Jpeak_input_setting", u"\u91c7\u6837\u7387(Hz)\uff1a", None))
|
||||
self.plainTextEdit_file_path_input.setPlainText("")
|
||||
self.plainTextEdit_file_path_input.setPlaceholderText(QCoreApplication.translate("MainWindow_detect_Jpeak_input_setting", u"\u6587\u4ef6\u8def\u5f84", None))
|
||||
self.groupBox_deepmodel_path.setTitle(QCoreApplication.translate("MainWindow_detect_Jpeak_input_setting", u"\u68c0\u6d4b\u6a21\u578b\u6587\u4ef6\u5939\u8def\u5f84", None))
|
||||
self.plainTextEdit_deepmodel_path.setPlaceholderText(QCoreApplication.translate("MainWindow_detect_Jpeak_input_setting", u"\u6587\u4ef6\u5939\u8def\u5f84", None))
|
||||
self.groupBox_file_path_save.setTitle(QCoreApplication.translate("MainWindow_detect_Jpeak_input_setting", u"\u7b97\u6cd5\u8bc6\u522b\u51fa\u7684J\u5cf0\u4fdd\u5b58\u8def\u5f84", None))
|
||||
self.plainTextEdit_file_path_save.setPlaceholderText(QCoreApplication.translate("MainWindow_detect_Jpeak_input_setting", u"\u4fdd\u5b58\u8def\u5f84", None))
|
||||
self.pushButton_confirm.setText(QCoreApplication.translate("MainWindow_detect_Jpeak_input_setting", u"\u786e\u5b9a", None))
|
||||
# retranslateUi
|
||||
|
||||
138
ui/setting/detect_Jpeak_input_setting.ui
Normal file
138
ui/setting/detect_Jpeak_input_setting.ui
Normal file
@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow_detect_Jpeak_input_setting</class>
|
||||
<widget class="QMainWindow" name="MainWindow_detect_Jpeak_input_setting">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>487</width>
|
||||
<height>417</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>导入设置</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="3">
|
||||
<widget class="QPushButton" name="pushButton_cancel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>取消</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>文件路径</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="2,1,1">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_file_path_input">
|
||||
<property name="title">
|
||||
<string>滤波后的BCG路径</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="1,2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>采样率(Hz):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_input_freq">
|
||||
<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>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit_file_path_input">
|
||||
<property name="plainText">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>文件路径</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_deepmodel_path">
|
||||
<property name="title">
|
||||
<string>检测模型文件夹路径</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit_deepmodel_path">
|
||||
<property name="placeholderText">
|
||||
<string>文件夹路径</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_file_path_save">
|
||||
<property name="title">
|
||||
<string>算法识别出的J峰保存路径</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit_file_path_save">
|
||||
<property name="placeholderText">
|
||||
<string>保存路径</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButton_confirm">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>确定</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
116
ui/setting/preprocess_input_setting.py
Normal file
116
ui/setting/preprocess_input_setting.py
Normal file
@ -0,0 +1,116 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'preprocess_input_setting.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.8.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QFont, QFontDatabase, QGradient, QIcon,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QGridLayout, QGroupBox, QHBoxLayout,
|
||||
QLabel, QMainWindow, QPlainTextEdit, QPushButton,
|
||||
QSizePolicy, QSpinBox, QVBoxLayout, QWidget)
|
||||
|
||||
class Ui_MainWindow_preprocess_input_setting(object):
|
||||
def setupUi(self, MainWindow_preprocess_input_setting):
|
||||
if not MainWindow_preprocess_input_setting.objectName():
|
||||
MainWindow_preprocess_input_setting.setObjectName(u"MainWindow_preprocess_input_setting")
|
||||
MainWindow_preprocess_input_setting.resize(487, 373)
|
||||
self.centralwidget = QWidget(MainWindow_preprocess_input_setting)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.gridLayout = QGridLayout(self.centralwidget)
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
self.pushButton_cancel = QPushButton(self.centralwidget)
|
||||
self.pushButton_cancel.setObjectName(u"pushButton_cancel")
|
||||
font = QFont()
|
||||
font.setPointSize(12)
|
||||
self.pushButton_cancel.setFont(font)
|
||||
|
||||
self.gridLayout.addWidget(self.pushButton_cancel, 2, 3, 1, 1)
|
||||
|
||||
self.groupBox = QGroupBox(self.centralwidget)
|
||||
self.groupBox.setObjectName(u"groupBox")
|
||||
self.verticalLayout_2 = QVBoxLayout(self.groupBox)
|
||||
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
||||
self.groupBox_file_path_input = QGroupBox(self.groupBox)
|
||||
self.groupBox_file_path_input.setObjectName(u"groupBox_file_path_input")
|
||||
self.verticalLayout_3 = QVBoxLayout(self.groupBox_file_path_input)
|
||||
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
||||
self.horizontalLayout = QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.label = QLabel(self.groupBox_file_path_input)
|
||||
self.label.setObjectName(u"label")
|
||||
self.label.setFont(font)
|
||||
|
||||
self.horizontalLayout.addWidget(self.label)
|
||||
|
||||
self.spinBox_input_freq = QSpinBox(self.groupBox_file_path_input)
|
||||
self.spinBox_input_freq.setObjectName(u"spinBox_input_freq")
|
||||
self.spinBox_input_freq.setFont(font)
|
||||
self.spinBox_input_freq.setMinimum(1)
|
||||
self.spinBox_input_freq.setMaximum(1000000)
|
||||
|
||||
self.horizontalLayout.addWidget(self.spinBox_input_freq)
|
||||
|
||||
|
||||
self.verticalLayout_3.addLayout(self.horizontalLayout)
|
||||
|
||||
self.plainTextEdit_file_path_input = QPlainTextEdit(self.groupBox_file_path_input)
|
||||
self.plainTextEdit_file_path_input.setObjectName(u"plainTextEdit_file_path_input")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.plainTextEdit_file_path_input)
|
||||
|
||||
self.verticalLayout_3.setStretch(0, 1)
|
||||
self.verticalLayout_3.setStretch(1, 2)
|
||||
|
||||
self.verticalLayout_2.addWidget(self.groupBox_file_path_input)
|
||||
|
||||
self.groupBox_file_path_save = QGroupBox(self.groupBox)
|
||||
self.groupBox_file_path_save.setObjectName(u"groupBox_file_path_save")
|
||||
self.verticalLayout_4 = QVBoxLayout(self.groupBox_file_path_save)
|
||||
self.verticalLayout_4.setObjectName(u"verticalLayout_4")
|
||||
self.plainTextEdit_file_path_save = QPlainTextEdit(self.groupBox_file_path_save)
|
||||
self.plainTextEdit_file_path_save.setObjectName(u"plainTextEdit_file_path_save")
|
||||
|
||||
self.verticalLayout_4.addWidget(self.plainTextEdit_file_path_save)
|
||||
|
||||
|
||||
self.verticalLayout_2.addWidget(self.groupBox_file_path_save)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 4)
|
||||
|
||||
self.pushButton_confirm = QPushButton(self.centralwidget)
|
||||
self.pushButton_confirm.setObjectName(u"pushButton_confirm")
|
||||
self.pushButton_confirm.setFont(font)
|
||||
|
||||
self.gridLayout.addWidget(self.pushButton_confirm, 2, 2, 1, 1)
|
||||
|
||||
MainWindow_preprocess_input_setting.setCentralWidget(self.centralwidget)
|
||||
|
||||
self.retranslateUi(MainWindow_preprocess_input_setting)
|
||||
|
||||
QMetaObject.connectSlotsByName(MainWindow_preprocess_input_setting)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, MainWindow_preprocess_input_setting):
|
||||
MainWindow_preprocess_input_setting.setWindowTitle(QCoreApplication.translate("MainWindow_preprocess_input_setting", u"\u5bfc\u5165\u8bbe\u7f6e", None))
|
||||
self.pushButton_cancel.setText(QCoreApplication.translate("MainWindow_preprocess_input_setting", u"\u53d6\u6d88", None))
|
||||
self.groupBox.setTitle(QCoreApplication.translate("MainWindow_preprocess_input_setting", u"\u6587\u4ef6\u8def\u5f84", None))
|
||||
self.groupBox_file_path_input.setTitle(QCoreApplication.translate("MainWindow_preprocess_input_setting", u"\u539f\u59cb\u4fe1\u53f7\u8def\u5f84", None))
|
||||
self.label.setText(QCoreApplication.translate("MainWindow_preprocess_input_setting", u"\u91c7\u6837\u7387(Hz)\uff1a", None))
|
||||
self.plainTextEdit_file_path_input.setPlainText("")
|
||||
self.plainTextEdit_file_path_input.setPlaceholderText(QCoreApplication.translate("MainWindow_preprocess_input_setting", u"\u6587\u4ef6\u8def\u5f84", None))
|
||||
self.groupBox_file_path_save.setTitle(QCoreApplication.translate("MainWindow_preprocess_input_setting", u"\u6ee4\u6ce2\u540e\u4fdd\u5b58\u8def\u5f84", None))
|
||||
self.plainTextEdit_file_path_save.setPlaceholderText(QCoreApplication.translate("MainWindow_preprocess_input_setting", u"\u4fdd\u5b58\u8def\u5f84", None))
|
||||
self.pushButton_confirm.setText(QCoreApplication.translate("MainWindow_preprocess_input_setting", u"\u786e\u5b9a", None))
|
||||
# retranslateUi
|
||||
|
||||
122
ui/setting/preprocess_input_setting.ui
Normal file
122
ui/setting/preprocess_input_setting.ui
Normal file
@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow_preprocess_input_setting</class>
|
||||
<widget class="QMainWindow" name="MainWindow_preprocess_input_setting">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>487</width>
|
||||
<height>373</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>导入设置</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="3">
|
||||
<widget class="QPushButton" name="pushButton_cancel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>取消</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>文件路径</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_file_path_input">
|
||||
<property name="title">
|
||||
<string>原始信号路径</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="1,2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>采样率(Hz):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_input_freq">
|
||||
<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>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit_file_path_input">
|
||||
<property name="plainText">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>文件路径</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_file_path_save">
|
||||
<property name="title">
|
||||
<string>滤波后保存路径</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit_file_path_save">
|
||||
<property name="placeholderText">
|
||||
<string>保存路径</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButton_confirm">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>确定</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Reference in New Issue
Block a user