winedrrawio.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. # -*- coding: utf-8 -*-
  2. """
  3. Class for reading data from WinEdr, a software tool written by
  4. John Dempster.
  5. WinEdr is free:
  6. http://spider.science.strath.ac.uk/sipbs/software.htm
  7. Author: Samuel Garcia
  8. """
  9. from __future__ import unicode_literals, print_function, division, absolute_import
  10. from .baserawio import (BaseRawIO, _signal_channel_dtype, _unit_channel_dtype,
  11. _event_channel_dtype)
  12. import numpy as np
  13. import os
  14. import sys
  15. class WinEdrRawIO(BaseRawIO):
  16. extensions = ['EDR', 'edr']
  17. rawmode = 'one-file'
  18. def __init__(self, filename=''):
  19. BaseRawIO.__init__(self)
  20. self.filename = filename
  21. def _source_name(self):
  22. return self.filename
  23. def _parse_header(self):
  24. with open(self.filename, 'rb') as fid:
  25. headertext = fid.read(2048)
  26. headertext = headertext.decode('ascii')
  27. header = {}
  28. for line in headertext.split('\r\n'):
  29. if '=' not in line:
  30. continue
  31. # print '#' , line , '#'
  32. key, val = line.split('=')
  33. if key in ['NC', 'NR', 'NBH', 'NBA', 'NBD', 'ADCMAX', 'NP', 'NZ', 'ADCMAX']:
  34. val = int(val)
  35. elif key in ['AD', 'DT', ]:
  36. val = val.replace(',', '.')
  37. val = float(val)
  38. header[key] = val
  39. self._raw_signals = np.memmap(self.filename, dtype='int16', mode='r',
  40. shape=(header['NP'] // header['NC'], header['NC'],),
  41. offset=header['NBH'])
  42. DT = header['DT']
  43. if 'TU' in header:
  44. if header['TU'] == 'ms':
  45. DT *= .001
  46. self._sampling_rate = 1. / DT
  47. sig_channels = []
  48. for c in range(header['NC']):
  49. YCF = float(header['YCF%d' % c].replace(',', '.'))
  50. YAG = float(header['YAG%d' % c].replace(',', '.'))
  51. YZ = float(header['YZ%d' % c].replace(',', '.'))
  52. ADCMAX = header['ADCMAX']
  53. AD = header['AD']
  54. name = header['YN%d' % c]
  55. chan_id = header['YO%d' % c]
  56. units = header['YU%d' % c]
  57. gain = AD / (YCF * YAG * (ADCMAX + 1))
  58. offset = -YZ * gain
  59. group_id = 0
  60. sig_channels.append((name, chan_id, self._sampling_rate, 'int16',
  61. units, gain, offset, group_id))
  62. sig_channels = np.array(sig_channels, dtype=_signal_channel_dtype)
  63. # No events
  64. event_channels = []
  65. event_channels = np.array(event_channels, dtype=_event_channel_dtype)
  66. # No spikes
  67. unit_channels = []
  68. unit_channels = np.array(unit_channels, dtype=_unit_channel_dtype)
  69. # fille into header dict
  70. self.header = {}
  71. self.header['nb_block'] = 1
  72. self.header['nb_segment'] = [1]
  73. self.header['signal_channels'] = sig_channels
  74. self.header['unit_channels'] = unit_channels
  75. self.header['event_channels'] = event_channels
  76. # insert some annotation at some place
  77. self._generate_minimal_annotations()
  78. def _segment_t_start(self, block_index, seg_index):
  79. return 0.
  80. def _segment_t_stop(self, block_index, seg_index):
  81. t_stop = self._raw_signals.shape[0] / self._sampling_rate
  82. return t_stop
  83. def _get_signal_size(self, block_index, seg_index, channel_indexes):
  84. return self._raw_signals.shape[0]
  85. def _get_signal_t_start(self, block_index, seg_index, channel_indexes):
  86. return 0.
  87. def _get_analogsignal_chunk(self, block_index, seg_index, i_start, i_stop, channel_indexes):
  88. # WARNING check if id or index for signals (in the old IO it was ids
  89. # ~ raw_signals = self._raw_signals[slice(i_start, i_stop), channel_indexes]
  90. if channel_indexes is None:
  91. channel_indexes = np.arange(self.header['signal_channels'].size)
  92. l = self.header['signal_channels']['id'].tolist()
  93. channel_ids = [l.index(c) for c in channel_indexes]
  94. raw_signals = self._raw_signals[slice(i_start, i_stop), channel_ids]
  95. return raw_signals