RespCoarseAlignment/RespCoarseAlign.py

620 lines
28 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
@author:andrew
@file:RespCoarseAlign.py
@email:admin@marques22.com
@email:2021022362@m.scnu.edu.cn
@time:2023/09/20
"""
import sys
from pathlib import Path
import pyedflib
import numpy as np
import pandas as pd
from PySide6.QtGui import QPixmap, QImage
from PySide6.QtWidgets import QApplication, QMainWindow, QFileDialog, QMessageBox, QWidget, QPushButton
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
from scipy import signal
from ui.Mian import Ui_mainWindow as Ui_respCoarseAlign
from ui.setings import Ui_MainWindow as Ui_Setting
import yaml
Conf = {
"PSGConfig": {
"Path": "./Data/PSG/",
"Frequency": 100,
"THOChannel": {
"auto": True,
"Channel": 3,
},
"ABDChannel": {
"auto": True,
"Channel": 4,
},
},
"XXConfig": {
"Path": "./Data/XX/",
"Frequency": 100,
},
"RespFilterConfig": {
"LowPass": 0.01,
"HighPass": 0.7,
"order": 4
},
"ApplyFrequency": 5
}
ButtonState = {
"Default": {
"pushButton_Refresh": True,
"pushButton_OpenFile": True,
"pushButton_Standardize": False,
"pushButton_CutOff": False,
"pushButton_GetPos": False,
"pushButton_Align": False,
"pushButton_JUMP": False,
"pushButton_EM1": False,
"pushButton_EM10": False,
"pushButton_EM100": False,
"pushButton_EP1": False,
"pushButton_EP10": False,
"pushButton_EP100": False,
"pushButton_SaveInfo": False,
"pushButton_Exit": True},
"Current": {
"pushButton_Refresh": True,
"pushButton_OpenFile": True,
"pushButton_Standardize": False,
"pushButton_CutOff": False,
"pushButton_GetPos": False,
"pushButton_Align": False,
"pushButton_JUMP": False,
"pushButton_EM1": False,
"pushButton_EM10": False,
"pushButton_EM100": False,
"pushButton_EP1": False,
"pushButton_EP10": False,
"pushButton_EP100": False,
"pushButton_SaveInfo": False,
"pushButton_Exit": True}
}
class SettingWindow(QMainWindow):
def __init__(self):
super(SettingWindow, self).__init__()
self.ui = Ui_Setting()
self.ui.setupUi(self)
self.__read_settings__()
def __read_settings__(self):
with open("./config.yaml", "r") as f:
fileConfig = yaml.load(f.read(), Loader=yaml.FullLoader)
Conf.update(fileConfig)
# print(Conf)
self.ui.lineEdit_PSGFilePath.setText(Conf["PSGConfig"]["Path"])
self.ui.lineEdit_XXFilePath.setText(Conf["XXConfig"]["Path"])
self.ui.spinBox_PSGDefaultFreq.setValue(Conf["PSGConfig"]["Frequency"])
self.ui.spinBox_XXDefaultFreq.setValue(Conf["XXConfig"]["Frequency"])
self.ui.QSpinBox_ApplyFre.setValue(Conf["ApplyFrequency"])
autoTHO = Conf["PSGConfig"]["THOChannel"]["auto"]
self.ui.checkBox_THOautoChannel.setChecked(2 if autoTHO else 0)
autoABD = Conf["PSGConfig"]["ABDChannel"]["auto"]
self.ui.checkBox_ABDautoChannel.setChecked(2 if autoABD else 0)
self.ui.spinBox_THOcustomChannel.setValue(Conf["PSGConfig"]["THOChannel"]["Channel"])
self.ui.spinBox_ABDcustomChannel.setValue(Conf["PSGConfig"]["ABDChannel"]["Channel"])
self.ui.doubleSpinBox_ButterLowPassFreq.setValue(Conf["RespFilterConfig"]["LowCut"])
self.ui.doubleSpinBox_ButterHighPassFreq.setValue(Conf["RespFilterConfig"]["HighCut"])
self.ui.spinBox_ButterOrder.setValue(Conf["RespFilterConfig"]["Order"])
self.ui.spinBox_THOcustomChannel.setEnabled(not autoTHO)
self.ui.spinBox_ABDcustomChannel.setEnabled(not autoABD)
# 绑定事件
self.ui.toolButton_PSGFilePath.clicked.connect(self.__select_file__)
self.ui.toolButton_XXFilePath.clicked.connect(self.__select_file__)
self.ui.pushButton_SaveConfig.clicked.connect(self.__write_settings__)
self.ui.pushButton_Cancel.clicked.connect(self.close)
# ABD auto checkbox和SpinBox 互斥
self.ui.checkBox_ABDautoChannel.stateChanged.connect(self.__ABDAutoChannel__)
self.ui.checkBox_THOautoChannel.stateChanged.connect(self.__THOAutoChannel__)
def __ABDAutoChannel__(self, state):
if state == 2:
self.ui.spinBox_ABDcustomChannel.setEnabled(False)
else:
self.ui.spinBox_ABDcustomChannel.setEnabled(True)
def __THOAutoChannel__(self, state):
if state == 2:
self.ui.spinBox_THOcustomChannel.setEnabled(False)
else:
self.ui.spinBox_THOcustomChannel.setEnabled(True)
def __select_file__(self, event):
sender = self.sender()
if sender.objectName() == "toolButton_PSGFilePath":
path = QFileDialog.getExistingDirectory(self, "选择PSG数据文件夹", "./Data/PSG/")
self.ui.lineEdit_PSGFilePath.setText(path)
elif sender.objectName() == "toolButton_XXFilePath":
path = QFileDialog.getExistingDirectory(self, "选择XX数据文件夹", "./Data/XX/")
self.ui.lineEdit_XXFilePath.setText(path)
def __write_settings__(self):
# 从界面读取配置
Conf["PSGConfig"]["Path"] = self.ui.lineEdit_PSGFilePath.text()
Conf["XXConfig"]["Path"] = self.ui.lineEdit_XXFilePath.text()
Conf["PSGConfig"]["Frequency"] = self.ui.spinBox_PSGDefaultFreq.value()
Conf["XXConfig"]["Frequency"] = self.ui.spinBox_XXDefaultFreq.value()
Conf["ApplyFrequency"] = self.ui.QSpinBox_ApplyFre.value()
Conf["PSGConfig"]["THOChannel"]["auto"] = self.ui.checkBox_THOautoChannel.isChecked()
Conf["PSGConfig"]["ABDChannel"]["auto"] = self.ui.checkBox_ABDautoChannel.isChecked()
Conf["PSGConfig"]["THOChannel"]["Channel"] = self.ui.spinBox_THOcustomChannel.value()
Conf["PSGConfig"]["ABDChannel"]["Channel"] = self.ui.spinBox_ABDcustomChannel.value()
Conf["RespFilterConfig"]["LowCut"] = self.ui.doubleSpinBox_ButterLowPassFreq.value()
Conf["RespFilterConfig"]["HighCut"] = self.ui.doubleSpinBox_ButterHighPassFreq.value()
Conf["RespFilterConfig"]["Order"] = self.ui.spinBox_ButterOrder.value()
with open("./config.yaml", "w") as f:
yaml.dump(Conf, f)
self.close()
class Data:
def __init__(self, PSGDataPath, XXDataPath, sampNo, Config):
self.PSGDataPath = PSGDataPath / f"{sampNo}.edf"
if (XXDataPath / f"{sampNo}.npy").exists():
self.XXDataPath = XXDataPath / f"{sampNo}.npy"
elif (XXDataPath / f"{sampNo}.txt").exists():
self.XXDataPath = XXDataPath / f"{sampNo}.txt"
else:
self.XXDataPath = None
self.Config = Config
self.raw_THO = None
self.raw_ABD = None
self.raw_XX = None
self.processed_THO = None
self.processed_ABD = None
self.processed_XX = None
self.PSG_minutes = None
self.XX_minutes = None
def OpenFile(self):
# 判断是edf还是npy或txt
if self.PSGDataPath.suffix == ".edf":
PSG = pyedflib.EdfReader(self.PSGDataPath.__str__())
if self.Config["PSGConfig"]["THOChannel"]["auto"]:
self.raw_THO = PSG.readSignal(PSG.getSignalLabels().index('Effort THO'))
else:
self.raw_THO = PSG.readSignal(self.Config["PSGConfig"]["THOChannel"]["Channel"])
if self.Config["PSGConfig"]["ABDChannel"]["auto"]:
self.raw_ABD = PSG.readSignal(PSG.getSignalLabels().index('Effort ABD'))
else:
self.raw_ABD = PSG.readSignal(self.Config["PSGConfig"]["ABDChannel"]["Channel"])
PSG.close()
else:
return False, "PSG文件格式错误"
if self.XXDataPath.suffix == ".npy":
self.raw_XX = np.load(self.XXDataPath)
elif self.XXDataPath.suffix == ".txt":
self.raw_XX = pd.read_csv(self.XXDataPath, sep="\t", header=None).values
else:
return False, "XX文件格式错误"
# 获取时长
# print(self.raw_THO.shape, self.raw_XX.shape)
# print(self.Config["PSGConfig"]["Frequency"], self.Config["XXConfig"]["Frequency"])
self.PSG_minutes = round(self.raw_THO.shape[0] / self.Config["PSGConfig"]["Frequency"] / 60)
self.XX_minutes = round(self.raw_XX.shape[0] / self.Config["XXConfig"]["Frequency"] / 60)
return True, "读取成功"
def __Filter__(self):
def butter_bandpass_filter(data, lowCut, highCut, fs, order):
low = lowCut / (fs * 0.5)
high = highCut / (fs * 0.5)
sos = signal.butter(order, [low, high], btype="bandpass", output='sos')
return signal.sosfilt(sos, data)
# 滤波
self.processed_THO = butter_bandpass_filter(self.raw_THO, self.Config["RespFilterConfig"]["LowCut"],
self.Config["RespFilterConfig"]["HighCut"],
self.Config["PSGConfig"]["Frequency"],
self.Config["RespFilterConfig"]["Order"])
self.processed_ABD = butter_bandpass_filter(self.raw_ABD, self.Config["RespFilterConfig"]["LowCut"],
self.Config["RespFilterConfig"]["HighCut"],
self.Config["PSGConfig"]["Frequency"],
self.Config["RespFilterConfig"]["Order"])
self.processed_XX = butter_bandpass_filter(self.raw_XX, self.Config["RespFilterConfig"]["LowCut"],
self.Config["RespFilterConfig"]["HighCut"],
self.Config["XXConfig"]["Frequency"],
self.Config["RespFilterConfig"]["Order"])
return
def Standardize_0(self):
# 重采样
self.processed_THO = signal.resample(self.raw_THO, int(self.PSG_minutes * 60 * self.Config["ApplyFrequency"]))
self.processed_ABD = signal.resample(self.raw_ABD, int(self.PSG_minutes * 60 * self.Config["ApplyFrequency"]))
self.processed_XX = signal.resample(self.raw_XX, int(self.XX_minutes * 60 * self.Config["ApplyFrequency"]))
return True, "原始信号仅重采样"
def Standardize_1(self):
self.__Filter__()
return True, "呼吸提取完成 "
def Standardize_2(self):
# 如果XX采样率大于PSG采样率那么XX重采样到PSG采样率
if self.Config["XXConfig"]["Frequency"] > self.Config["PSGConfig"]["Frequency"]:
# 用[::]完成
self.processed_XX = self.processed_XX[
::int(self.Config["XXConfig"]["Frequency"] / self.Config["PSGConfig"]["Frequency"])]
# 如果XX采样率小于PSG采样率那么XX重采样到PSG采样率
elif self.Config["XXConfig"]["Frequency"] < self.Config["PSGConfig"]["Frequency"] < 100:
# 用repeat完成
self.processed_XX = np.repeat(self.processed_XX,
int(self.Config["PSGConfig"]["Frequency"] / self.Config["XXConfig"][
"Frequency"]),
axis=0)
# 修改Config
self.Config.update({"temp_frequency": self.Config["PSGConfig"]["Frequency"]})
return True, "预重采样完成"
def Standardize_3(self):
temp_frequency = self.Config["temp_frequency"]
# 判断是否去基线
if self.Config["PSGConfig"]["PSGDelBase"]:
# 减去四秒钟平均滤波
self.processed_THO = self.processed_THO - np.convolve(self.processed_THO,
np.ones(int(4 * temp_frequency)) / int(
4 * temp_frequency),
mode='same')
self.processed_ABD = self.processed_ABD - np.convolve(self.processed_ABD,
np.ones(int(4 * temp_frequency)) / int(
4 * temp_frequency),
mode='same')
if self.Config["XXConfig"]["XXDelBase"]:
self.processed_XX = self.processed_XX - np.convolve(self.processed_XX,
np.ones(int(4 * temp_frequency)) / int(
4 * temp_frequency),
mode='same')
return True, "去基线完成"
def Standardize_4(self):
# 判断是否标准化
if self.Config["PSGConfig"]["PSGZScore"]:
self.processed_THO = (self.processed_THO - np.mean(self.processed_THO)) / np.std(self.processed_THO)
self.processed_ABD = (self.processed_ABD - np.mean(self.processed_ABD)) / np.std(self.processed_ABD)
if self.Config["XXConfig"]["XXZScore"]:
self.processed_XX = (self.processed_XX - np.mean(self.processed_XX)) / np.std(self.processed_XX)
return True, "标准化完成"
def Standardize_5(self):
# 重采样
self.processed_THO = signal.resample(self.processed_THO,
int(self.PSG_minutes * 60 * self.Config["ApplyFrequency"]))
self.processed_ABD = signal.resample(self.processed_ABD,
int(self.PSG_minutes * 60 * self.Config["ApplyFrequency"]))
self.processed_XX = signal.resample(self.processed_XX,
int(self.XX_minutes * 60 * self.Config["ApplyFrequency"]))
return True, "最终重采样完成"
def DrawPicRawOverview(self):
fig = Figure(figsize=(8, 7), dpi=100)
canvas = FigureCanvas(fig)
max_x = max(self.processed_THO.shape[0], self.processed_ABD.shape[0], self.processed_XX.shape[0])
ax1 = fig.add_subplot(311)
ax1.plot(self.processed_THO, color='blue')
ax1.set_xlim(0, max_x)
ax1.set_title("THO")
ax2 = fig.add_subplot(312)
ax2.plot(self.processed_XX, color='blue')
ax2.set_xlim(0, max_x)
ax2.set_title("xinxiao")
ax3 = fig.add_subplot(313)
ax3.plot(self.processed_ABD, color='blue')
ax3.set_xlim(0, max_x)
ax3.set_title("ABD")
width, height = fig.figbbox.width, fig.figbbox.height
fig.canvas.draw()
# 返回图片以便存到QPixIamge
return canvas.buffer_rgba(), width, height
def DrawPicOverviewWithCutOff(self):
fig = Figure(figsize=(8, 7), dpi=100)
canvas = FigureCanvas(fig)
max_x = max(self.processed_THO.shape[0] + self.Config["PSGConfig"]["PreA"],
self.processed_XX.shape[0] + self.Config["XXConfig"]["PreA"])
min_x = min(self.Config["PSGConfig"]["PreA"], self.Config["XXConfig"]["PreA"], 0)
ax1 = fig.add_subplot(311)
ax1.plot(
np.linspace(self.Config["PSGConfig"]["PreA"], len(self.processed_THO) + self.Config["PSGConfig"]["PreA"],
len(self.processed_THO)), self.processed_THO, color='blue')
# 绘制x = PreCut的线 和 x = PostCut的虚线
ax1.axvline(x=self.Config["PSGConfig"]["PreCut"] + self.Config["PSGConfig"]["PreA"], color='red',
linestyle='--')
ax1.axvline(x=len(self.processed_THO) - self.Config["PSGConfig"]["PostCut"] + self.Config["PSGConfig"]["PreA"],
color='red', linestyle='--')
ax1.set_xlim(min_x, max_x)
ax1.set_title("THO")
ax2 = fig.add_subplot(312)
ax2.plot(np.linspace(self.Config["XXConfig"]["PreA"], len(self.processed_XX) + self.Config["XXConfig"]["PreA"],
len(self.processed_XX)), self.processed_XX, color='blue')
ax2.axvline(x=self.Config["XXConfig"]["PreCut"] + self.Config["XXConfig"]["PreA"], color='red', linestyle='--')
ax2.axvline(x=len(self.processed_XX) - self.Config["XXConfig"]["PostCut"] + self.Config["XXConfig"]["PreA"],
color='red', linestyle='--')
ax2.set_xlim(min_x, max_x)
ax2.set_title("xinxiao")
ax3 = fig.add_subplot(313)
ax3.plot(
np.linspace(self.Config["PSGConfig"]["PreA"], len(self.processed_ABD) + self.Config["PSGConfig"]["PreA"],
len(self.processed_ABD)), self.processed_ABD, color='blue')
ax3.axvline(x=self.Config["PSGConfig"]["PreCut"] + self.Config["PSGConfig"]["PreA"], color='red',
linestyle='--')
ax3.axvline(x=len(self.processed_THO) - self.Config["PSGConfig"]["PostCut"] + self.Config["PSGConfig"]["PreA"],
color='red', linestyle='--')
ax3.set_xlim(min_x, max_x)
ax3.set_title("ABD")
width, height = fig.figbbox.width, fig.figbbox.height
fig.canvas.draw()
# 返回图片以便存到QPixIamge
return canvas.buffer_rgba(), width, height
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_respCoarseAlign()
self.setting = SettingWindow()
self.ui.setupUi(self)
self.ui.actionDefault_Configuration.triggered.connect(self.setting.show)
# checkbox custom 和SpinBox 互斥
self.ui.checkBox_custom.stateChanged.connect(self.__customChannel__)
self.__disableAllButton__()
# 绑定事件
# 刷新键分别获取PSG和XX文件夹里面的数据获取所有编号显示在下拉框比对编号同时存在的可选仅存在一个文件夹的编号不可选
self.ui.pushButton_Refresh.clicked.connect(self.__refresh__)
self.ui.pushButton_OpenFile.clicked.connect(self.__openFile__)
self.ui.pushButton_Standardize.clicked.connect(self.__standardize__)
self.ui.pushButton_CutOff.clicked.connect(self.__cutOff__)
self.ui.pushButton_GetPos.clicked.connect(self.__getPosition__)
# self.ui.pushButton_Align.clicked.connect(self.__align__)
# self.ui.pushButton_JUMP.clicked.connect(self.__jump__)
# self.ui.pushButton_EM1.clicked.connect(self.__EM1__)
# self.ui.pushButton_EM10.clicked.connect(self.__EM10__)
# self.ui.pushButton_EM100.clicked.connect(self.__EM100__)
# self.ui.pushButton_EP1.clicked.connect(self.__EP1__)
# self.ui.pushButton_EP10.clicked.connect(self.__EP10__)
# self.ui.pushButton_EP100.clicked.connect(self.__EP100__)
# self.ui.pushButton_SaveInfo.clicked.connect(self.__saveInfo__)
self.ui.pushButton_Exit.clicked.connect(self.__exit__)
def __resset__(self):
ButtonState["Current"].update(ButtonState["Default"].copy())
ButtonState["Current"]["pushButton_Standardize"] = True
self.ui.spinBox_PSGPreA.setValue(0)
self.ui.spinBox_PSGPreCut.setValue(0)
self.ui.spinBox_PSGPostCut.setValue(0)
self.ui.spinBox_XXPreA.setValue(0)
self.ui.spinBox_XXPreCut.setValue(0)
self.ui.spinBox_XXPostCut.setValue(0)
self.ui.checkBox_NABD.setChecked(False)
self.ui.checkBox_NTHO.setChecked(False)
self.ui.checkBox_PABD.setChecked(False)
self.ui.checkBox_PTHO.setChecked(False)
self.ui.checkBox_custom.setChecked(False)
self.ui.spinBox_SelectEpoch.setValue(0)
self.ui.spinBox_custom.setValue(0)
def __cutOff__(self):
Conf2 = self.data.Config.copy()
Conf2["PSGConfig"].update({"PreA": self.ui.spinBox_PSGPreA.value(),
"PreCut": self.ui.spinBox_PSGPreCut.value(),
"PostCut": self.ui.spinBox_PSGPostCut.value()})
Conf2["XXConfig"].update({"PreA": self.ui.spinBox_XXPreA.value(),
"PreCut": self.ui.spinBox_XXPreCut.value(),
"PostCut": self.ui.spinBox_XXPostCut.value()})
self.data.Config = Conf2
self.__plot__()
# matplotlib 绘制图像
def __plot__(self):
# 判读是哪个按钮点击调用的本程序
if self.sender() == self.ui.pushButton_Standardize:
buffer, width, height = self.data.DrawPicRawOverview()
elif self.sender() == self.ui.pushButton_CutOff:
buffer, width, height = self.data.DrawPicOverviewWithCutOff()
else:
return
# 显示到labelPic上
img = QImage(buffer, width, height, QImage.Format_RGBA8888)
self.ui.label_Pic.setPixmap(QPixmap(img))
# noinspection PyUnresolvedReferences
def __exit__(self):
# 选择是否确认退出
reply = QMessageBox.question(self, '确认', '确认退出吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
self.close()
def __customChannel__(self, state):
if state == 2:
self.ui.spinBox_custom.setEnabled(True)
else:
self.ui.spinBox_custom.setEnabled(False)
# 刷新键分别获取PSG和XX文件夹里面的数据获取所有编号显示在下拉框比对编号同时存在的可选仅存在一个文件夹的编号不可选
def __refresh__(self):
# 检查两文件夹是否存在
PSGPath = Path(self.setting.ui.lineEdit_PSGFilePath.text())
XXPath = Path(self.setting.ui.lineEdit_XXFilePath.text())
if not PSGPath.exists():
QMessageBox.warning(self, "警告", "PSG文件夹不存在")
return
if not XXPath.exists():
QMessageBox.warning(self, "警告", "XX文件夹不存在")
return
# 获取两文件夹下所有的txt和npy文件编号
PSGFiles = [file.stem for file in PSGPath.glob("*.edf")]
XXFiles = [file.stem for file in XXPath.glob("*.txt")] + [file.stem for file in XXPath.glob("*.npy")]
sorted(PSGFiles)
sorted(XXFiles)
# 获取两文件夹下同时存在的编号
print(PSGFiles, XXFiles)
Files = list(set(PSGFiles).intersection(set(XXFiles)))
# 获取两文件夹下仅存在一个的编号
FilesOnlyInPSG = list(set(PSGFiles).difference(set(XXFiles)))
FilesOnlyInXX = list(set(XXFiles).difference(set(PSGFiles)))
print(Files, FilesOnlyInPSG, FilesOnlyInXX)
# 均显示到下拉框
self.ui.comboBox_SelectFile.clear()
self.ui.comboBox_SelectFile.addItems([file for file in Files])
self.ui.comboBox_SelectFile.addItems([file + " (仅PSG)" for file in FilesOnlyInPSG])
self.ui.comboBox_SelectFile.addItems([file + " (仅XX)" for file in FilesOnlyInXX])
self.ui.comboBox_SelectFile.setCurrentIndex(0)
# # 仅存在一个文件夹的编号不可选
for file in FilesOnlyInPSG:
self.ui.comboBox_SelectFile.model().item(FilesOnlyInPSG.index(file) + len(Files)).setEnabled(False)
for file in FilesOnlyInXX:
self.ui.comboBox_SelectFile.model().item(
FilesOnlyInXX.index(file) + len(Files) + len(FilesOnlyInPSG)).setEnabled(False)
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(ButtonState["Current"][widget.objectName()])
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 __openFile__(self):
self.ui.label_Info.setText("正在打开文件...")
self.__disableAllButton__()
# 长时间操作,刷新界面防止卡顿
QApplication.processEvents()
# 获取checkbox状态
self.data = Data(Path(self.setting.ui.lineEdit_PSGFilePath.text()),
Path(self.setting.ui.lineEdit_XXFilePath.text()),
self.ui.comboBox_SelectFile.currentText().split(" ")[0],
Conf)
opened, info = self.data.OpenFile()
if not opened:
QMessageBox.warning(self, "警告", info)
self.ui.label_Info.setText(info)
else:
self.ui.label_PSGmins.setText(str(self.data.PSG_minutes))
self.ui.label_XXmins.setText(str(self.data.XX_minutes))
self.ui.progressBar.setValue(100)
self.ui.label_Info.setText(info)
self.__resset__()
self.__enableAllButton__()
def __standardize__(self):
self.ui.progressBar.setValue(0)
self.ui.label_Info.setText("正在标准化...")
self.__disableAllButton__()
QApplication.processEvents()
Conf2 = self.data.Config.copy()
Conf2["RawSignal"] = self.ui.checkBox_RawSignal.isChecked()
Conf2["PSGConfig"].update({
"PSGDelBase": self.ui.checkBox_PSGDelBase.isChecked(),
"PSGZScore": self.ui.checkBox_PSGZScore.isChecked(),
"Frequency": self.ui.spinBox_PSGFreq.value(),
})
Conf2["XXConfig"].update({
"XXDelBase": self.ui.checkBox_XXDelBase.isChecked(),
"XXZScore": self.ui.checkBox_XXZScore.isChecked(),
"Frequency": self.ui.spinBox_XXFreq.value(),
})
self.data.Config = Conf2
if self.data.Config["RawSignal"]:
opened, info = self.data.Standardize_0()
if not opened:
QMessageBox.warning(self, "警告", info)
self.ui.label_Info.setText(info)
else:
self.ui.progressBar.setValue(100)
self.ui.label_Info.setText(info)
else:
self.ui.label_Info.setText('正在进行呼吸提取...')
QApplication.processEvents()
opened, info = self.data.Standardize_1()
self.ui.label_Info.setText(info)
self.ui.progressBar.setValue(10)
QApplication.processEvents()
opened, info = self.data.Standardize_2()
self.ui.progressBar.setValue(30)
self.ui.label_Info.setText(info)
QApplication.processEvents()
opened, info = self.data.Standardize_3()
self.ui.label_Info.setText(info)
self.ui.progressBar.setValue(50)
QApplication.processEvents()
opened, info = self.data.Standardize_4()
self.ui.label_Info.setText(info)
self.ui.progressBar.setValue(70)
QApplication.processEvents()
opened, info = self.data.Standardize_5()
self.ui.label_Info.setText(info)
self.ui.progressBar.setValue(90)
QApplication.processEvents()
self.__plot__()
self.ui.progressBar.setValue(100)
ButtonState["Current"]["pushButton_CutOff"] = True
ButtonState["Current"]["pushButton_GetPos"] = True
self.__enableAllButton__()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())