2022-03-27 22:10:32 +08:00
|
|
|
|
# -*- coding: cp936 -*-
|
2022-03-29 22:18:46 +08:00
|
|
|
|
# ʹ<><CAB9>gbk<62><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܶ<EFBFBD><DCB6><EFBFBD>ǩ
|
2022-03-27 22:10:32 +08:00
|
|
|
|
"""
|
|
|
|
|
@author:Marques
|
|
|
|
|
@file:Prepare_Data.py
|
|
|
|
|
@email:admin@marques22.com
|
|
|
|
|
@email:2021022362@m.scnu.edu.cn
|
|
|
|
|
@time:2022/03/26
|
|
|
|
|
"""
|
2022-03-29 22:18:46 +08:00
|
|
|
|
import time
|
|
|
|
|
from typing import List
|
|
|
|
|
import logging
|
2022-03-27 22:10:32 +08:00
|
|
|
|
import pyedflib
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
import numpy as np
|
|
|
|
|
import pandas as pd
|
|
|
|
|
from matplotlib import pyplot as plt, gridspec
|
2022-03-30 09:59:40 +08:00
|
|
|
|
from utils.Preprocessing import BCG_Operation
|
2022-03-27 22:10:32 +08:00
|
|
|
|
from tqdm import tqdm
|
2022-03-29 22:18:46 +08:00
|
|
|
|
from datetime import datetime
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
plt.rcParams['font.sans-serif'] = ['SimHei'] # <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>ı<EFBFBD>ǩ
|
|
|
|
|
plt.rcParams['axes.unicode_minus'] = False # <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
# ['EEG F3-A2', 'EEG F4-A1', 'EEG C3-A2', 'EEG C4-A1', 'EEG O1-A2',
|
|
|
|
|
# 'EEG O2-A1', 'EOG Right', 'EOG Left', 'EMG Chin', 'ECG I', 'RR',
|
|
|
|
|
# 'ECG II', 'Effort Tho', 'Flow Patient', 'Flow Patient', 'Effort Abd',
|
|
|
|
|
# 'SpO2', 'Pleth', 'Snore', 'Body', 'Pulse', 'Leg LEG1', 'Leg LEG2',
|
|
|
|
|
# 'EEG A1-A2', 'Imp']
|
|
|
|
|
|
2022-03-29 22:18:46 +08:00
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
|
|
|
|
logger = logging.getLogger()
|
|
|
|
|
logger.setLevel(logging.NOTSET)
|
|
|
|
|
realtime = time.strftime('%Y%m%d', time.localtime(time.time()))
|
2022-03-30 09:59:40 +08:00
|
|
|
|
fh = logging.FileHandler(Path("history") / (realtime + ".log"), mode='a')
|
2022-03-29 22:18:46 +08:00
|
|
|
|
fh.setLevel(logging.NOTSET)
|
|
|
|
|
fh.setFormatter(logging.Formatter("%(asctime)s: %(message)s"))
|
|
|
|
|
logger.addHandler(fh)
|
|
|
|
|
|
|
|
|
|
ch = logging.StreamHandler()
|
|
|
|
|
ch.setLevel(logging.NOTSET)
|
|
|
|
|
ch.setFormatter(logging.Formatter("%(asctime)s: %(message)s"))
|
|
|
|
|
logger.addHandler(ch)
|
|
|
|
|
logging.getLogger('matplotlib.font_manager').disabled = True
|
|
|
|
|
logging.info("------------------------------------")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Quality_Relabel:
|
2022-03-27 22:10:32 +08:00
|
|
|
|
# <20><>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8>
|
|
|
|
|
base_channel = ['EEG F3-A2', 'EEG F4-A1', 'EEG C3-A2', 'EEG C4-A1', 'EEG O1-A2', 'EEG O2-A1', 'EOG Right',
|
|
|
|
|
'EOG Left', 'EMG Chin', 'ECG I', 'RR', 'ECG II', 'Effort Tho', 'Flow Patient', 'Flow Patient', 'HR',
|
|
|
|
|
'Effort Abd', 'SpO2', 'Pleth', 'Snore', 'Body', 'Pulse', 'Leg LEG1', 'Leg LEG2', 'EEG A1-A2', 'Imp']
|
|
|
|
|
|
|
|
|
|
# <20><>ʾ<EFBFBD>¼<EFBFBD>
|
2022-03-29 22:18:46 +08:00
|
|
|
|
base_event = ["Hypopnea", "Central apnea", "Obstructive apnea", "Mixed apnea", "Desaturation"]
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
# <20>趨<EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ɫ
|
2022-03-29 22:18:46 +08:00
|
|
|
|
# event_code color event
|
|
|
|
|
# 0 <20><>ɫ <20><><EFBFBD><EFBFBD>
|
|
|
|
|
# 1 <20><>ɫ <20><>ͨ<EFBFBD><CDA8>
|
|
|
|
|
# 2 <20><>ɫ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
# 3 <20><>ɫ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
# 4 <20><>ɫ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
# 5 <20><>ɫ Ѫ<><D1AA><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6>½<EFBFBD>
|
2022-03-30 10:17:03 +08:00
|
|
|
|
color_cycle = ["blue", "pink", "orange", "red", "grey", "green"]
|
2022-03-27 22:10:32 +08:00
|
|
|
|
assert len(color_cycle) == len(base_event) + 1, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>"
|
|
|
|
|
|
|
|
|
|
def __init__(self, sampNo: int, frequency: int = 100, bcg_frequency: int = 1000,
|
|
|
|
|
channel_list: List[str] = ['Effort Tho', 'Effort Abd', 'SpO2', 'Flow Patient', 'Flow Patient'],
|
|
|
|
|
focus_event_list: List[str] = ["Obstructive apnea"]):
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
:param sampNo: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>
|
|
|
|
|
:param frequency: <EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param bcg_frequency: BCG<EFBFBD>źŲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param channel_list: <EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>
|
|
|
|
|
:param focus_event_list: <EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>ͣ<EFBFBD>¼<EFBFBD>
|
|
|
|
|
"""
|
|
|
|
|
self.sampNo = sampNo
|
|
|
|
|
self.channel_list = channel_list
|
|
|
|
|
self.focus_event_list = focus_event_list
|
|
|
|
|
self.frequency = frequency
|
|
|
|
|
self.bcg_frequency = bcg_frequency
|
|
|
|
|
|
|
|
|
|
self.ecg_start_time = None
|
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ɫʱ<C9AB><CAB1><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD>¼<EFBFBD>
|
|
|
|
|
self.ecg_event_label = None
|
|
|
|
|
self.bcg_event_label = None
|
2022-03-29 22:18:46 +08:00
|
|
|
|
self.spo2_event_label = None
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>ͣ<EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>б<EFBFBD>
|
|
|
|
|
self.ecg_event_label_filtered_df = None
|
|
|
|
|
self.bcg_event_label_filtered_df = None
|
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>б<EFBFBD>
|
|
|
|
|
self.ecg_event_label_df = None
|
|
|
|
|
self.bcg_event_label_df = None
|
|
|
|
|
|
|
|
|
|
# <20><>ͨ<EFBFBD><CDA8><EFBFBD>ź<EFBFBD>
|
|
|
|
|
self.signal_select = {}
|
|
|
|
|
|
|
|
|
|
self.check_channel()
|
|
|
|
|
self.read_data(frequency, bcg_frequency)
|
|
|
|
|
self.read_event()
|
|
|
|
|
|
|
|
|
|
def check_channel(self):
|
|
|
|
|
for i in self.channel_list:
|
|
|
|
|
if i not in self.base_channel:
|
2022-03-29 22:18:46 +08:00
|
|
|
|
logging.debug(f"{i} <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڳ<EFBFBD><DAB3><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
print(f"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>{self.channel_list}")
|
|
|
|
|
|
|
|
|
|
def read_data(self, frequency: int = 100, bcg_frequency: int = 1000):
|
2022-03-30 09:59:40 +08:00
|
|
|
|
bcg_path = Path(f"Data/BCG/{self.sampNo}samp.npy")
|
|
|
|
|
ecg_path = Path(f"Data/ECG/A{str(self.sampNo).rjust(7, '0')}.edf")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
if not bcg_path.exists():
|
2022-03-29 22:18:46 +08:00
|
|
|
|
logging.error(f"{bcg_path} <20><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
raise FileNotFoundError(f"{bcg_path} <20><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>")
|
|
|
|
|
|
|
|
|
|
if not ecg_path.exists():
|
2022-03-29 22:18:46 +08:00
|
|
|
|
logging.error(f"{ecg_path} <20><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
raise FileNotFoundError(f"{ecg_path} <20><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>")
|
|
|
|
|
|
|
|
|
|
with pyedflib.EdfReader(str(ecg_path.resolve())) as file:
|
|
|
|
|
signal_num = file.signals_in_file
|
2022-03-29 22:18:46 +08:00
|
|
|
|
logging.debug(f"{self.sampNo} EDF file signal number is {signal_num}")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
signal_label = file.getSignalLabels()
|
2022-03-29 22:18:46 +08:00
|
|
|
|
logging.debug(f"{self.sampNo} EDF file signal label : {signal_label}")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
self.ecg_start_time = file.getStartdatetime()
|
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD><EFBFBD>PSG<53><47>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>
|
|
|
|
|
self.ecg_event_label = np.zeros(file.getFileDuration() * self.frequency)
|
2022-03-29 22:18:46 +08:00
|
|
|
|
self.spo2_event_label = np.zeros(file.getFileDuration() * self.frequency)
|
2022-03-27 22:10:32 +08:00
|
|
|
|
# <20><>ӡPSG<53><47>Ϣ
|
|
|
|
|
file.file_info_long()
|
|
|
|
|
|
|
|
|
|
# sub_index <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>flow patient
|
|
|
|
|
sub_index = 1
|
|
|
|
|
|
2022-03-29 22:18:46 +08:00
|
|
|
|
logging.info("<EFBFBD><EFBFBD>ȡPSG<EFBFBD>źš<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
for i, index in enumerate(signal_label):
|
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD>е<EFBFBD>ͨ<EFBFBD><CDA8>
|
|
|
|
|
if index in self.channel_list:
|
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>flow patientͨ<74><CDA8>
|
|
|
|
|
if index == 'Flow Patient':
|
|
|
|
|
index = index + str(sub_index)
|
|
|
|
|
sub_index += 1
|
|
|
|
|
signal = file.readSignal(i)
|
|
|
|
|
sample_frequency = file.getSampleFrequency(i)
|
|
|
|
|
# <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
|
|
|
|
if sample_frequency < frequency:
|
|
|
|
|
signal = signal.repeat(frequency / sample_frequency)
|
|
|
|
|
elif sample_frequency > frequency:
|
|
|
|
|
signal = signal[::int(sample_frequency / frequency)]
|
|
|
|
|
self.signal_select[index] = signal
|
2022-03-29 22:18:46 +08:00
|
|
|
|
logging.info(f"<EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD>ȡPSG: {index}")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD>
|
2022-03-29 22:18:46 +08:00
|
|
|
|
logging.info("<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>źš<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
signal = np.load(bcg_path)
|
|
|
|
|
preprocessing = BCG_Operation(sample_rate=bcg_frequency)
|
|
|
|
|
# 20Hz<48><7A>ͨȥ<CDA8><C8A5>
|
|
|
|
|
signal1 = preprocessing.Butterworth(signal, 'lowpass', low_cut=20, order=3)
|
|
|
|
|
# 0.7Hz <20><>ͨ<EFBFBD><CDA8>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
|
|
|
|
signal2 = preprocessing.Butterworth(signal, 'lowpass', low_cut=0.7, order=3)
|
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
signal1 = signal1[::int(bcg_frequency / frequency)]
|
|
|
|
|
signal2 = signal2[::int(bcg_frequency / frequency)]
|
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>¼
|
|
|
|
|
self.bcg_event_label = np.zeros(len(signal))
|
|
|
|
|
self.signal_select['xin_xiao'] = signal1
|
|
|
|
|
self.signal_select['xin_xiao_respire'] = signal2
|
|
|
|
|
|
|
|
|
|
def read_event(self):
|
2022-03-30 09:59:40 +08:00
|
|
|
|
bcg_label_path = Path(f"Data/BCG_label/{self.sampNo}_label_all.csv")
|
|
|
|
|
ecg_label_path = Path(f"Data/ECG_label/export{self.sampNo}.csv")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
if not bcg_label_path.exists():
|
2022-03-29 22:18:46 +08:00
|
|
|
|
logging.error(f"{bcg_label_path} <20><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
raise FileNotFoundError(f"{bcg_label_path} <20><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>")
|
|
|
|
|
|
|
|
|
|
if not ecg_label_path.exists():
|
2022-03-29 22:18:46 +08:00
|
|
|
|
logging.error(f"{ecg_label_path} <20><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
raise FileNotFoundError(f"{ecg_label_path} <20><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>")
|
|
|
|
|
|
|
|
|
|
df = pd.read_csv(ecg_label_path, encoding='gbk')
|
|
|
|
|
self.ecg_event_label_df = df
|
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD>˲<EFBFBD><CBB2><EFBFBD>ע<EFBFBD><D7A2><EFBFBD>¼<EFBFBD>
|
2022-03-29 22:18:46 +08:00
|
|
|
|
df2 = df[df["Event type"].isin(self.focus_event_list)]
|
2022-03-27 22:10:32 +08:00
|
|
|
|
# <20><><EFBFBD><EFBFBD>epoch<63><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2022-03-29 22:18:46 +08:00
|
|
|
|
df2 = df2.sort_values(by='Epoch')
|
|
|
|
|
self.ecg_event_label_filtered_df = df2
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
2022-03-29 22:18:46 +08:00
|
|
|
|
logging.info("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>PSG<EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")
|
|
|
|
|
for one_data in tqdm(df.index, ncols=80):
|
2022-03-27 22:10:32 +08:00
|
|
|
|
one_data = df.loc[one_data]
|
|
|
|
|
|
|
|
|
|
# ͨ<><CDA8><EFBFBD><EFBFBD>ʼ<EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
event_start_time = datetime.strptime(one_data["Date"] + " " + one_data["Time"], '%Y/%m/%d %H:%M:%S')
|
|
|
|
|
SP = (event_start_time - self.ecg_start_time).seconds
|
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD>Ž<EFBFBD><C5BD><EFBFBD><EFBFBD>з֣<D0B7><D6A3><EFBFBD><EFBFBD><EFBFBD>Duration 20 (20) <20><><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD>ŵ<EFBFBD><C5B5><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
EP = int(SP + float(one_data["Duration"].split("(")[0]))
|
|
|
|
|
SP *= self.frequency
|
|
|
|
|
EP *= self.frequency
|
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>±<EFBFBD><C2B1>벢<EFBFBD>浽<EFBFBD>¼<EFBFBD><C2BC><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>
|
|
|
|
|
if one_data["Event type"] == "Hypopnea":
|
|
|
|
|
self.ecg_event_label[SP:EP] = 1
|
|
|
|
|
elif one_data["Event type"] == "Central apnea":
|
|
|
|
|
self.ecg_event_label[SP:EP] = 2
|
|
|
|
|
elif one_data["Event type"] == "Obstructive apnea":
|
|
|
|
|
self.ecg_event_label[SP:EP] = 3
|
|
|
|
|
elif one_data["Event type"] == "Mixed apnea":
|
|
|
|
|
self.ecg_event_label[SP:EP] = 4
|
2022-03-29 22:18:46 +08:00
|
|
|
|
elif one_data["Event type"] == "Desaturation":
|
|
|
|
|
self.spo2_event_label[SP:EP] = 5
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
# <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
|
|
|
|
|
df = pd.read_csv(bcg_label_path, encoding='gbk')
|
|
|
|
|
df["new_start"] = df["new_start"].astype("int")
|
|
|
|
|
df["new_end"] = df["new_end"].astype("int")
|
|
|
|
|
self.bcg_event_label_df = df
|
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD>˲<EFBFBD><CBB2><EFBFBD>ע<EFBFBD>¼<EFBFBD>
|
2022-03-29 22:18:46 +08:00
|
|
|
|
df2 = df[df["Event type"].isin(self.focus_event_list)]
|
|
|
|
|
df2 = df2.sort_values(by='Epoch')
|
|
|
|
|
self.bcg_event_label_filtered_df = df2
|
|
|
|
|
logging.info("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")
|
|
|
|
|
for one_data in tqdm(df.index):
|
2022-03-27 22:10:32 +08:00
|
|
|
|
one_data = df.loc[one_data]
|
|
|
|
|
SP = one_data["new_start"] * self.frequency
|
|
|
|
|
EP = one_data["new_end"] * self.frequency
|
|
|
|
|
|
|
|
|
|
if one_data["Event type"] == "Hypopnea":
|
|
|
|
|
self.bcg_event_label[SP:EP] = 1
|
|
|
|
|
elif one_data["Event type"] == "Central apnea":
|
|
|
|
|
self.bcg_event_label[SP:EP] = 2
|
|
|
|
|
elif one_data["Event type"] == "Obstructive apnea":
|
|
|
|
|
self.bcg_event_label[SP:EP] = 3
|
|
|
|
|
elif one_data["Event type"] == "Mixed apnea":
|
|
|
|
|
self.bcg_event_label[SP:EP] = 4
|
|
|
|
|
|
|
|
|
|
# assert len(self.ecg_event_label_filtered_df) == len(self.bcg_event_label_filtered_df), \
|
|
|
|
|
# f"PSG<53><47><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>, PSG<53>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>{len(self.ecg_event_label_filtered_df)},
|
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>{len(self.bcg_event_label_filtered_df)}"
|
|
|
|
|
|
|
|
|
|
def show_one_event(self, bcg_index: int, ecg_index: int, front_add_second: int = 60,
|
2022-03-29 22:18:46 +08:00
|
|
|
|
back_add_second: int = 60):
|
2022-03-27 22:10:32 +08:00
|
|
|
|
"""
|
|
|
|
|
:param bcg_index: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD>csv<EFBFBD><EFBFBD><EFBFBD>к<EFBFBD>
|
|
|
|
|
:param ecg_index: PSG<EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD>csv<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param front_add_second: <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
|
|
|
|
|
:param back_add_second: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
2022-03-29 22:18:46 +08:00
|
|
|
|
# <20><>ȡ<EFBFBD>¼<EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>csv<73>ļ<EFBFBD><C4BC>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
bcg_real_index = self.bcg_event_label_filtered_df.index[bcg_index],
|
|
|
|
|
ecg_real_index = self.ecg_event_label_filtered_df.index[ecg_index],
|
|
|
|
|
one_bcg_data = self.bcg_event_label_df.loc[bcg_real_index]
|
|
|
|
|
one_ecg_data = self.ecg_event_label_df.loc[ecg_real_index]
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
# <20><>ȡECG<43>¼<EFBFBD><C2BC><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
|
|
|
|
event_start_time = datetime.strptime(one_ecg_data["Date"] + " " + one_ecg_data["Time"], '%Y/%m/%d %H:%M:%S')
|
|
|
|
|
ecg_SP = (event_start_time - self.ecg_start_time).seconds
|
|
|
|
|
ecg_duration = int(float(str(one_ecg_data["Duration"]).split("(")[0]) + 0.5)
|
|
|
|
|
ecg_EP = ecg_SP + ecg_duration
|
|
|
|
|
|
|
|
|
|
# <20><>ȡBCG<43>¼<EFBFBD><C2BC><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
|
|
|
|
bcg_SP = one_bcg_data["new_start"]
|
|
|
|
|
bcg_EP = one_bcg_data["new_end"]
|
|
|
|
|
bcg_duration = int(float(str(one_bcg_data["Duration"]).split("(")[0]))
|
2022-03-29 22:18:46 +08:00
|
|
|
|
|
|
|
|
|
logging.info(f"sampNo:{self.sampNo} "
|
|
|
|
|
f"bcg[index:{bcg_index} epoch:{one_bcg_data['Epoch']} event:{one_bcg_data['Event type']}] "
|
|
|
|
|
f"ecg:[index:{ecg_index} epoch:{one_ecg_data['Epoch']} event:{one_ecg_data['Event type']}]")
|
|
|
|
|
|
|
|
|
|
if one_bcg_data['Event type'] != one_ecg_data['Event type']:
|
|
|
|
|
logging.error(f"sampNo:{self.sampNo} PSG<53>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䲻һ<E4B2BB>£<EFBFBD><C2A3><EFBFBD><EFBFBD>Ų<EFBFBD>"
|
|
|
|
|
f"bcg[index:{bcg_index} epoch:{one_bcg_data['Epoch']} event:{one_bcg_data['Event type']}] "
|
|
|
|
|
f"ecg:[index:{ecg_index} epoch:{one_ecg_data['Epoch']} event:{one_ecg_data['Event type']}]")
|
|
|
|
|
raise ValueError()
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ
|
|
|
|
|
ecg_SP = ecg_SP - front_add_second
|
|
|
|
|
ecg_EP = ecg_EP + back_add_second
|
|
|
|
|
bcg_SP = bcg_SP - front_add_second - (ecg_duration - bcg_duration) // 2
|
|
|
|
|
bcg_EP = bcg_EP + back_add_second + (ecg_duration - bcg_duration) // 2
|
|
|
|
|
|
|
|
|
|
# <20><>ͼ
|
|
|
|
|
plt.figure(figsize=(12, 6), dpi=150)
|
2022-03-29 22:18:46 +08:00
|
|
|
|
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ֮<CDBC><D6AE><EFBFBD>ı<EFBFBD><C4B1><EFBFBD>
|
|
|
|
|
gs = gridspec.GridSpec(7, 1, height_ratios=[1, 1, 1, 1, 1, 3, 1])
|
2022-03-27 22:10:32 +08:00
|
|
|
|
plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0)
|
|
|
|
|
plt.margins(0, 0)
|
|
|
|
|
plt.tight_layout()
|
|
|
|
|
|
2022-03-29 22:18:46 +08:00
|
|
|
|
# <20><><EFBFBD><EFBFBD> Flow1
|
2022-03-27 22:10:32 +08:00
|
|
|
|
plt.subplot(gs[0])
|
2022-03-29 22:18:46 +08:00
|
|
|
|
self.plt_channel(plt_=plt, SP=ecg_SP, EP=ecg_EP, channel="Flow Patient1")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
2022-03-29 22:18:46 +08:00
|
|
|
|
# <20><><EFBFBD><EFBFBD> Flow2
|
2022-03-27 22:10:32 +08:00
|
|
|
|
plt.subplot(gs[1])
|
2022-03-29 22:18:46 +08:00
|
|
|
|
self.plt_channel(plt_=plt, SP=ecg_SP, EP=ecg_EP, channel="Flow Patient2",
|
|
|
|
|
title=f"PSG sampNo:{self.sampNo} Epoch:{one_ecg_data['Epoch']} Duration:{one_ecg_data['Duration']}")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
plt.subplot(gs[2])
|
2022-03-29 22:18:46 +08:00
|
|
|
|
self.plt_channel(plt_=plt, SP=ecg_SP, EP=ecg_EP, channel="Effort Tho")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
plt.subplot(gs[3])
|
2022-03-29 22:18:46 +08:00
|
|
|
|
self.plt_channel(plt_=plt, SP=ecg_SP, EP=ecg_EP, channel="Effort Abd")
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
plt.subplot(gs[4])
|
2022-03-29 22:18:46 +08:00
|
|
|
|
self.plt_channel(plt_=plt, SP=ecg_SP, EP=ecg_EP, channel="SpO2", event_code=[5])
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
plt.subplot(gs[5])
|
2022-03-30 10:17:03 +08:00
|
|
|
|
self.plt_channel(plt_=plt, SP=bcg_SP, EP=bcg_EP, channel="xin_xiao", event_show_under=False)
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
|
|
|
|
plt.subplot(gs[6])
|
2022-03-30 10:17:03 +08:00
|
|
|
|
self.plt_channel(plt_=plt, SP=bcg_SP, EP=bcg_EP, channel="xin_xiao_respire", event_show_under=False,
|
2022-03-29 22:18:46 +08:00
|
|
|
|
ax_bottom=True,
|
|
|
|
|
title=f"<EFBFBD><EFBFBD><EFBFBD><EFBFBD> sampNo:{self.sampNo} Epoch:{one_bcg_data['Epoch']} Duration:{one_bcg_data['Duration']}",
|
|
|
|
|
)
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
2022-03-30 10:17:03 +08:00
|
|
|
|
figManager = plt.get_current_fig_manager()
|
|
|
|
|
figManager.window.showMaximized()
|
2022-03-27 22:10:32 +08:00
|
|
|
|
plt.show()
|
|
|
|
|
|
2022-03-29 22:18:46 +08:00
|
|
|
|
def plt_channel(self, plt_, SP, EP, channel, event_code=[1, 2, 3, 4], event_show_under=False,
|
|
|
|
|
ax_top=False, ax_bottom=False, ax_left=True, ax_right=False, title=None):
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
:param plt_:
|
|
|
|
|
:param SP: <EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param EP: <EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param channel: ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param event_code: Ҫ<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param event_show_under: <EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param ax_top: <EFBFBD><EFBFBD>ʾ<EFBFBD>Ͽ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param ax_bottom: <EFBFBD><EFBFBD>ʾ<EFBFBD>¿<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param ax_left: <EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param ax_right: <EFBFBD><EFBFBD>ʾ<EFBFBD>ҿ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:param title: <EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
plt_.plot(np.linspace(SP, EP, (EP - SP) * self.frequency),
|
|
|
|
|
self.signal_select[channel][SP * self.frequency:EP * self.frequency], label=channel)
|
|
|
|
|
|
|
|
|
|
for j in event_code:
|
|
|
|
|
if channel == "SpO2":
|
|
|
|
|
mask = self.spo2_event_label[SP * self.frequency:EP * self.frequency] == j
|
|
|
|
|
else:
|
|
|
|
|
mask = self.ecg_event_label[SP * self.frequency:EP * self.frequency] == j
|
|
|
|
|
if event_show_under:
|
|
|
|
|
min_point = self.signal_select[channel][SP * self.frequency:EP * self.frequency].min()
|
|
|
|
|
len_segment = EP * self.frequency - SP * self.frequency
|
|
|
|
|
y = (min_point.repeat(len_segment) * mask).astype('float')
|
|
|
|
|
np.place(y, y == 0, np.nan)
|
|
|
|
|
else:
|
|
|
|
|
y = (self.signal_select[channel][SP * self.frequency:EP * self.frequency] * mask).astype('float')
|
|
|
|
|
np.place(y, y == 0, np.nan)
|
|
|
|
|
plt_.plot(np.linspace(SP, EP, (EP - SP) * self.frequency), y, color=self.color_cycle[j])
|
|
|
|
|
plt_.legend(loc=1)
|
2022-03-27 22:10:32 +08:00
|
|
|
|
|
2022-03-29 22:18:46 +08:00
|
|
|
|
if title is not None:
|
|
|
|
|
plt_.title(title)
|
|
|
|
|
ax = plt.gca()
|
|
|
|
|
ax.spines["top"].set_visible(ax_top)
|
|
|
|
|
ax.spines["right"].set_visible(ax_right)
|
|
|
|
|
ax.spines["bottom"].set_visible(ax_bottom)
|
|
|
|
|
ax.spines["left"].set_visible(ax_left)
|
|
|
|
|
# xticks = [[]] if xticks else [range(SP, EP, 5), [str(i) for i in range(0, (EP - SP), 5)]]
|
|
|
|
|
# print(xticks)
|
|
|
|
|
# plt_.xticks(*xticks) # ȥ<><C8A5>x<EFBFBD><78>
|
|
|
|
|
|
|
|
|
|
def show_all_event(self, start_bcg_index: int = 0, shifting: int = 0, front_add_second: int = 60,
|
|
|
|
|
back_add_second: int = 60):
|
|
|
|
|
|
|
|
|
|
for index in range(start_bcg_index, len(self.bcg_event_label_filtered_df)):
|
|
|
|
|
self.show_one_event(index,
|
|
|
|
|
index + shifting,
|
2022-03-27 22:10:32 +08:00
|
|
|
|
front_add_second=front_add_second,
|
2022-03-29 22:18:46 +08:00
|
|
|
|
back_add_second=back_add_second
|
2022-03-27 22:10:32 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2022-03-29 22:18:46 +08:00
|
|
|
|
prepareData = Quality_Relabel(670)
|
2022-03-27 22:10:32 +08:00
|
|
|
|
prepareData.show_all_event()
|