123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- """保存数据为bdf格式"""
- import logging
- import pyedflib
- logger = logging.getLogger(__name__)
- class SigSaveHigh():
- """数据保存类:使用highlevel API,简化了保存代码,
- 一次保存一个文件"""
- def __init__(self, mne_raw_data):
- """初始化SigSave
- Args:
- mne_raw_data (class): mne.io.array.array.RawArray
- """
- self.raw_data = mne_raw_data
- def save(self, file_name, name, gender):
- """保存
- Args:
- file_name (str): 保存的文件名
- name (Optional[str], optional): bdf头信息中的姓名. Defaults to None.
- gender (Optional[str], optional): bdf头信息中的性别. Defaults to None.
- """
- signals = self.raw_data.get_data()
- channel_names = self.raw_data.info.get_montage().ch_names
- signal_headers = pyedflib.highlevel.make_signal_headers(
- channel_names, sample_frequency=self.raw_data.info["sfreq"])
- header = pyedflib.highlevel.make_header(patientname=name, gender=gender)
- pyedflib.highlevel.write_edf(file_name, signals, signal_headers, header)
- class SigSave():
- """数据保存类: 使用基本的保存API,可以持续将数据写入一个文件"""
- def __init__(self, channel_labels, sample_rate, physical_max, physical_min):
- """初始化保存数据类
- Args:
- channel_labels (list): 导联标签,例如:['C3','C4']
- sample_rate (int): 采样率
- physical_max (int): 最大物理值,与设备相关, 例如pony:375000 neo:200000
- physical_min (int): 最小物理值,与设备相关, 例如pony:-375000 neo:-200000
- """
- self.channel_labels = channel_labels
- self.sample_rate = sample_rate
- self.physical_max = physical_max
- self.physical_min = physical_min
- self.is_ready = False
- self.is_first = False
- def set_edf_header(self, subject, filename, task_per_run, path):
- """ 用于设置EDF头部信息
- Args:
- subject (class): 受试数据库实体
- path (str): 存储数据路径
- """
- channel_info = []
- channel_count = len(self.channel_labels)
- self.path = path + "/" + filename
- self.edf_w = pyedflib.EdfWriter(self.path,
- channel_count,
- file_type=pyedflib.FILETYPE_BDFPLUS)
- for label_num in range(channel_count):
- ch_dict = {
- "label": self.channel_labels[label_num],
- "dimension": "uV",
- "sample_frequency": self.sample_rate,
- "physical_max": self.physical_max,
- "physical_min": self.physical_min,
- "digital_max": 8388607,
- "digital_min": -8388608,
- }
- channel_info.append(ch_dict)
- self.edf_w.setSignalHeaders(channel_info)
- self.edf_w.setPatientName(subject.name)
- if subject.gender == "男":
- self.edf_w.setGender(1)
- elif subject.gender == "女":
- self.edf_w.setGender(0)
- self.edf_w.setBirthdate(subject.birthday)
- self.edf_w.setPatientCode(subject.id_card)
- self.edf_w.setRecordingAdditional(str(task_per_run))
- self.is_ready = True
- self.is_first = True
- self.start_record_timestamp = 0
- def save_raw_data(self, signals, timestamp=None):
- """向打开的文件写入数据,可以持续写入,直到调用close_edf_file时则无法写入
- Args:
- signals (np array): 需要保存的数据,channels*samples
- """
- if self.is_ready:
- if self.is_first and timestamp:
- self.start_record_timestamp = timestamp
- self.is_first = False
- self.edf_w.writeSamples(signals)
- else:
- logger.info(
- "not ready for save, maybe edf/bdf header has not been set")
- def edf_data_mark(self, timestamp, mark: str):
- """给数据打标记
- Args:
- timestamp (int): 标记的时间点
- mark (str): 标记的信息
- """
- if self.is_ready:
- time_seconds = (timestamp - self.start_record_timestamp) / 1000
- self.edf_w.writeAnnotation(time_seconds, -1, mark)
- else:
- logger.info(
- "not ready for save, maybe edf/bdf header has not been set")
- def close_edf_file(self):
- """关闭BDF文件
- """
- self.edf_w.close()
- self.is_ready = False
|