2
0

sig_save.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. """保存数据为bdf格式"""
  2. import logging
  3. import pyedflib
  4. logger = logging.getLogger(__name__)
  5. class SigSaveHigh():
  6. """数据保存类:使用highlevel API,简化了保存代码,
  7. 一次保存一个文件"""
  8. def __init__(self, mne_raw_data):
  9. """初始化SigSave
  10. Args:
  11. mne_raw_data (class): mne.io.array.array.RawArray
  12. """
  13. self.raw_data = mne_raw_data
  14. def save(self, file_name, name, gender):
  15. """保存
  16. Args:
  17. file_name (str): 保存的文件名
  18. name (Optional[str], optional): bdf头信息中的姓名. Defaults to None.
  19. gender (Optional[str], optional): bdf头信息中的性别. Defaults to None.
  20. """
  21. signals = self.raw_data.get_data()
  22. channel_names = self.raw_data.info.get_montage().ch_names
  23. signal_headers = pyedflib.highlevel.make_signal_headers(
  24. channel_names, sample_frequency=self.raw_data.info["sfreq"])
  25. header = pyedflib.highlevel.make_header(patientname=name, gender=gender)
  26. pyedflib.highlevel.write_edf(file_name, signals, signal_headers, header)
  27. class SigSave():
  28. """数据保存类: 使用基本的保存API,可以持续将数据写入一个文件"""
  29. def __init__(self, channel_labels, sample_rate, physical_max, physical_min):
  30. """初始化保存数据类
  31. Args:
  32. channel_labels (list): 导联标签,例如:['C3','C4']
  33. sample_rate (int): 采样率
  34. physical_max (int): 最大物理值,与设备相关, 例如pony:375000 neo:200000
  35. physical_min (int): 最小物理值,与设备相关, 例如pony:-375000 neo:-200000
  36. """
  37. self.channel_labels = channel_labels
  38. self.sample_rate = sample_rate
  39. self.physical_max = physical_max
  40. self.physical_min = physical_min
  41. self.is_ready = False
  42. self.is_first = False
  43. def set_edf_header(self, subject, filename, task_per_run, path):
  44. """ 用于设置EDF头部信息
  45. Args:
  46. subject (str): subject name
  47. path (str): 存储数据路径
  48. """
  49. channel_info = []
  50. channel_count = len(self.channel_labels)
  51. self.path = path + "/" + filename
  52. self.edf_w = pyedflib.EdfWriter(self.path,
  53. channel_count,
  54. file_type=pyedflib.FILETYPE_BDFPLUS)
  55. for label_num in range(channel_count):
  56. ch_dict = {
  57. "label": self.channel_labels[label_num],
  58. "dimension": "uV",
  59. "sample_frequency": self.sample_rate,
  60. "physical_max": self.physical_max,
  61. "physical_min": self.physical_min,
  62. "digital_max": 8388607,
  63. "digital_min": -8388608,
  64. }
  65. channel_info.append(ch_dict)
  66. self.edf_w.setSignalHeaders(channel_info)
  67. self.edf_w.setPatientName(subject)
  68. self.edf_w.setRecordingAdditional(str(task_per_run))
  69. self.is_ready = True
  70. self.is_first = True
  71. self.start_record_timestamp = 0
  72. def save_raw_data(self, signals, timestamp=None):
  73. """向打开的文件写入数据,可以持续写入,直到调用close_edf_file时则无法写入
  74. Args:
  75. signals (np array): 需要保存的数据,channels*samples
  76. """
  77. if self.is_ready:
  78. if self.is_first and timestamp:
  79. self.start_record_timestamp = timestamp
  80. self.is_first = False
  81. self.edf_w.writeSamples(signals)
  82. else:
  83. logger.info(
  84. "not ready for save, maybe edf/bdf header has not been set")
  85. def edf_data_mark(self, timestamp, mark: str):
  86. """给数据打标记
  87. Args:
  88. timestamp (int): 标记的时间点
  89. mark (str): 标记的信息
  90. """
  91. if self.is_ready:
  92. time_seconds = (timestamp - self.start_record_timestamp) / 1000
  93. self.edf_w.writeAnnotation(time_seconds, -1, mark)
  94. else:
  95. logger.info(
  96. "not ready for save, maybe edf/bdf header has not been set")
  97. def close_edf_file(self):
  98. """关闭BDF文件
  99. """
  100. self.edf_w.close()
  101. self.is_ready = False