Compare commits
7 Commits
efdbf5daae
...
aaac28c8b9
| Author | SHA1 | Date | |
|---|---|---|---|
| aaac28c8b9 | |||
| 64b6c136b9 | |||
| dab7bf1934 | |||
| 2b5cc322d7 | |||
| 517ad55517 | |||
| a0a8343e7c | |||
| d38b12b7ff |
@ -7,12 +7,11 @@ from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication
|
||||
from matplotlib.backends.backend_qt import NavigationToolbar2QT
|
||||
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
|
||||
from matplotlib.figure import Figure
|
||||
from numba import prange, njit
|
||||
from numpy import repeat, convolve, ones, mean, std, empty, int64, sum as np_sum, pad, zeros, array, argmax, linspace, \
|
||||
diff
|
||||
from overrides import overrides
|
||||
from pandas import read_csv, DataFrame
|
||||
from scipy.signal import find_peaks, resample, butter, sosfiltfilt
|
||||
from scipy.signal import find_peaks, resample, butter, sosfiltfilt, correlate
|
||||
from yaml import dump, load, FullLoader
|
||||
|
||||
from func.utils.PublicFunc import PublicFunc
|
||||
@ -856,10 +855,19 @@ class Data:
|
||||
self.processed_Abd = None
|
||||
|
||||
def open_file(self):
|
||||
if ((not Path(Config["Path"]["Input_orgBcg"]).exists())
|
||||
or (not Path(Config["Path"]["Input_Tho"]).exists())
|
||||
or (not Path(Config["Path"]["Input_Abd"]).exists())):
|
||||
return Result().failure(info=Constants.INPUT_FAILURE + Constants.APPROXIMATELY_ALIGN_FAILURE_REASON["Data_Path_Not_Exist"])
|
||||
|
||||
if not Path(Config["Path"]["Input_orgBcg"]).exists():
|
||||
return Result().failure(
|
||||
info=Constants.INPUT_FAILURE + "orgBcg: " + Constants.APPROXIMATELY_ALIGN_FAILURE_REASON[
|
||||
"Data_Path_Not_Exist"])
|
||||
if not Path(Config["Path"]["Input_Tho"]).exists():
|
||||
return Result().failure(
|
||||
info=Constants.INPUT_FAILURE + "Tho: " + Constants.APPROXIMATELY_ALIGN_FAILURE_REASON[
|
||||
"Data_Path_Not_Exist"])
|
||||
if not Path(Config["Path"]["Input_Abd"]).exists():
|
||||
return Result().failure(
|
||||
info=Constants.INPUT_FAILURE + "Abd: " + Constants.APPROXIMATELY_ALIGN_FAILURE_REASON[
|
||||
"Data_Path_Not_Exist"])
|
||||
|
||||
try:
|
||||
self.raw_orgBcg = read_csv(Config["Path"]["Input_orgBcg"],
|
||||
@ -1008,20 +1016,16 @@ class Data:
|
||||
def calculate_correlation1(self):
|
||||
# 计算互相关1/2
|
||||
try:
|
||||
# 计算因子
|
||||
MULTIPLE_FACTOER = ConfigParams.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Multiple_Factor"]
|
||||
a = self.processed_Tho[Config["PSGConfig"]["PreCut"]:len(self.processed_Tho) - Config["PSGConfig"]["PostCut"]].copy()
|
||||
v = self.processed_orgBcg[Config["orgBcgConfig"]["PreCut"]:len(self.processed_orgBcg) - Config["orgBcgConfig"]["PostCut"]].copy()
|
||||
a *= 100
|
||||
v *= 100
|
||||
a *= MULTIPLE_FACTOER
|
||||
v *= MULTIPLE_FACTOER
|
||||
a = a.astype(int64)
|
||||
v = v.astype(int64)
|
||||
a = pad(a, (len(v) - 1, len(v) - 1), mode='constant')
|
||||
tho_relate = zeros(len(a) - len(v) - 1, dtype=int64)
|
||||
len_calc = len(a) - len(v) - 1
|
||||
# 将序列分成一百份来计算
|
||||
for i in range(100):
|
||||
tho_relate[i * len_calc // 100:(i + 1) * len_calc // 100] = Data.get_Correlate(a, v, array(
|
||||
[i * len_calc // 100, (i + 1) * len_calc // 100], dtype=int64))
|
||||
tho_relate = tho_relate / 10000
|
||||
tho_relate = correlate(a, v, mode='full')
|
||||
tho_relate = tho_relate / (MULTIPLE_FACTOER ** 2)
|
||||
tho_relate2 = - tho_relate
|
||||
|
||||
result = {"tho_relate": tho_relate, "tho_relate2": tho_relate2}
|
||||
@ -1039,14 +1043,7 @@ class Data:
|
||||
v *= 100
|
||||
a = a.astype(int64)
|
||||
v = v.astype(int64)
|
||||
a = pad(a, (len(v) - 1, len(v) - 1), mode='constant')
|
||||
|
||||
abd_relate = zeros(len(a) - len(v) - 1, dtype=int64)
|
||||
len_calc = len(a) - len(v) - 1
|
||||
# 将序列分成一百份来计算
|
||||
for i in range(100):
|
||||
abd_relate[i * len_calc // 100:(i + 1) * len_calc // 100] = Data.get_Correlate(a, v, array(
|
||||
[i * len_calc // 100, (i + 1) * len_calc // 100], dtype=int64))
|
||||
abd_relate = correlate(a, v, mode='full')
|
||||
abd_relate = abd_relate / 10000
|
||||
abd_relate2 = - abd_relate
|
||||
|
||||
@ -1086,13 +1083,3 @@ class Data:
|
||||
|
||||
return Result().success(info=Constants.APPROXIMATELY_EPOCH_GET_FINISHED, data=result)
|
||||
|
||||
@staticmethod
|
||||
@njit("int64[:](int64[:],int64[:], int64[:])", nogil=True, parallel=True)
|
||||
def get_Correlate(a, v, between):
|
||||
begin, end = between
|
||||
if end == 0:
|
||||
end = len(a) - len(v) - 1
|
||||
result = empty(end - begin, dtype=int64)
|
||||
for i in prange(end - begin):
|
||||
result[i] = np_sum(a[begin + i: begin + i + len(v)] * v)
|
||||
return result
|
||||
@ -66,6 +66,7 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
@staticmethod
|
||||
def __read_config__():
|
||||
if not Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH).exists():
|
||||
Path(ConfigParams.PUBLIC_CONFIG_FILE_PATH).parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(ConfigParams.PUBLIC_CONFIG_FILE_PATH, "w") as f:
|
||||
dump(ConfigParams.PUBLIC_CONFIG_NEW_CONTENT, f)
|
||||
|
||||
@ -95,60 +96,90 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
def __slot_btn_approximately_align__(self):
|
||||
self.approximately_align = MainWindow_approximately_align()
|
||||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||||
sampID = int(self.ui.comboBox_sampID.currentText())
|
||||
self.approximately_align.show(root_path, sampID)
|
||||
sampID = self.ui.comboBox_sampID.currentText()
|
||||
if not self.check_root_path():
|
||||
return
|
||||
if not self.check_sampID():
|
||||
return
|
||||
self.approximately_align.show(root_path, int(sampID))
|
||||
|
||||
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())
|
||||
sampID = self.ui.comboBox_sampID.currentText()
|
||||
if sender == self.ui.pushButton_preprocess_BCG:
|
||||
mode = "BCG"
|
||||
elif sender == self.ui.pushButton_preprocess_ECG:
|
||||
mode = "ECG"
|
||||
else:
|
||||
raise ValueError("模式不存在")
|
||||
self.preprocess.show(mode, root_path, sampID)
|
||||
if not self.check_root_path():
|
||||
return
|
||||
if not self.check_sampID():
|
||||
return
|
||||
self.preprocess.show(mode, root_path, int(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)
|
||||
sampID = self.ui.comboBox_sampID.currentText()
|
||||
if not self.check_root_path():
|
||||
return
|
||||
if not self.check_sampID():
|
||||
return
|
||||
self.detect_Jpeak.show(root_path, int(sampID))
|
||||
|
||||
def __slot_btn_detect_Rpeak__(self):
|
||||
self.detect_Rpeak = MainWindow_detect_Rpeak()
|
||||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||||
sampID = int(self.ui.comboBox_sampID.currentText())
|
||||
self.detect_Rpeak.show(root_path, sampID)
|
||||
sampID = self.ui.comboBox_sampID.currentText()
|
||||
if not self.check_root_path():
|
||||
return
|
||||
if not self.check_sampID():
|
||||
return
|
||||
self.detect_Rpeak.show(root_path, int(sampID))
|
||||
|
||||
def __slot_btn_label_check__(self):
|
||||
self.label_check = MainWindow_label_check()
|
||||
|
||||
sender = self.sender()
|
||||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||||
sampID = int(self.ui.comboBox_sampID.currentText())
|
||||
sampID = self.ui.comboBox_sampID.currentText()
|
||||
|
||||
if not self.check_root_path():
|
||||
return
|
||||
if not self.check_sampID():
|
||||
return
|
||||
|
||||
if sender == self.ui.pushButton_label_check_BCG:
|
||||
mode = "BCG"
|
||||
elif sender == self.ui.pushButton_label_check_ECG:
|
||||
mode = "ECG"
|
||||
else:
|
||||
raise ValueError("模式不存在")
|
||||
self.label_check.show(mode, root_path, sampID)
|
||||
self.label_check.show(mode, root_path, int(sampID))
|
||||
|
||||
def __slot_btn_precisely_align__(self):
|
||||
self.precisely_align = MainWindow_precisely_align()
|
||||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||||
sampID = int(self.ui.comboBox_sampID.currentText())
|
||||
self.precisely_align.show(root_path, sampID)
|
||||
sampID = self.ui.comboBox_sampID.currentText()
|
||||
if not self.check_root_path():
|
||||
return
|
||||
if not self.check_sampID():
|
||||
return
|
||||
self.precisely_align.show(root_path, int(sampID))
|
||||
|
||||
def __slot_btn_cut_PSG__(self):
|
||||
self.cut_PSG = MainWindow_cut_PSG()
|
||||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||||
sampID = int(self.ui.comboBox_sampID.currentText())
|
||||
self.cut_PSG.show(root_path, sampID)
|
||||
sampID = self.ui.comboBox_sampID.currentText()
|
||||
if not self.check_root_path():
|
||||
return
|
||||
if not self.check_sampID():
|
||||
return
|
||||
self.cut_PSG.show(root_path, int(sampID))
|
||||
|
||||
def seek_sampID(self, path):
|
||||
if not Path(path).exists():
|
||||
@ -157,3 +188,15 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
|
||||
|
||||
sub_folders = [item.name for item in Path(path).iterdir() if item.is_dir()]
|
||||
self.ui.comboBox_sampID.addItems(sub_folders)
|
||||
|
||||
def check_root_path(self):
|
||||
if self.ui.plainTextEdit_root_path.toPlainText() == Constants.STRING_IS_EMPTY:
|
||||
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_ROOT_PATH_NOT_EXIST, Constants.MSGBOX_TYPE_ERROR)
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_sampID(self):
|
||||
if self.ui.comboBox_sampID.currentText() == Constants.STRING_IS_EMPTY:
|
||||
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_SAMPID_EMPTY, Constants.MSGBOX_TYPE_ERROR)
|
||||
return False
|
||||
return True
|
||||
|
||||
@ -42,7 +42,8 @@ class ConfigParams:
|
||||
"BandPassOrder": 4,
|
||||
"BandPassLow": 0.01,
|
||||
"BandPassHigh": 0.7
|
||||
}
|
||||
},
|
||||
"Multiple_Factor":100
|
||||
}
|
||||
APPROXIMATELY_ALIGN_INPUT_ORGBCG_FILENAME: str = "orgBcg_Raw_"
|
||||
APPROXIMATELY_ALIGN_INPUT_THO_FILENAME: str = "Effort Tho_Raw_"
|
||||
|
||||
@ -12,6 +12,7 @@ class Constants:
|
||||
MSGBOX_TYPE_QUESTION: str = "Question"
|
||||
|
||||
MAINWINDOW_ROOT_PATH_NOT_EXIST: str = "根目录路径输入错误"
|
||||
MAINWINDOW_SAMPID_EMPTY: str = "样本ID为空"
|
||||
MAINWINDOW_MSGBOX_TITLE: str = "消息"
|
||||
|
||||
INPUTTING_DATA: str = "正在导入数据"
|
||||
|
||||
16
run.py
16
run.py
@ -2,12 +2,11 @@ from logging import getLogger, NOTSET, FileHandler, Formatter, StreamHandler, in
|
||||
from pathlib import Path
|
||||
from sys import argv
|
||||
from time import strftime, localtime, time
|
||||
|
||||
import os
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
from func.Module_mainwindow import MainWindow
|
||||
|
||||
import importlib.util
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 设置日志
|
||||
@ -28,6 +27,17 @@ if __name__ == '__main__':
|
||||
getLogger('matplotlib.font_manager').disabled = True
|
||||
info("程序启动")
|
||||
|
||||
# 解决 Could not find the Qt platform plugin "windows"
|
||||
spec = importlib.util.find_spec("PySide6")
|
||||
if spec and spec.origin:
|
||||
dirname = Path(spec.origin).parent
|
||||
plugin_path = dirname / 'plugins' / 'platforms'
|
||||
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path.__str__()
|
||||
|
||||
# 解决 Error #15: Initializing libiomp5md.dll
|
||||
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
|
||||
|
||||
|
||||
app = QApplication(argv)
|
||||
app.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
|
||||
app.styleHints().setColorScheme(Qt.ColorScheme.Light) # 强制使用浅色模式
|
||||
|
||||
Reference in New Issue
Block a user