neuroscopeio.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. # -*- coding: utf-8 -*-
  2. """
  3. Reading from neuroscope format files.
  4. Ref: http://neuroscope.sourceforge.net/
  5. It is an old format from Buzsaki's lab.
  6. Supported: Read
  7. #TODO:
  8. SpikeTrain file '.clu' '.res'
  9. Event '.ext.evt' or '.evt.ext'
  10. Author: sgarcia
  11. """
  12. # needed for python 3 compatibility
  13. from __future__ import absolute_import
  14. import os
  15. from xml.etree import ElementTree
  16. import numpy as np
  17. import quantities as pq
  18. from neo.io.baseio import BaseIO
  19. from neo.io.rawbinarysignalio import RawBinarySignalIO
  20. from neo.core import (Block, Segment, ChannelIndex,
  21. AnalogSignal)
  22. class NeuroScopeIO(BaseIO):
  23. """
  24. """
  25. is_readable = True
  26. is_writable = False
  27. supported_objects = [ Block, Segment , AnalogSignal, ChannelIndex]
  28. readable_objects = [ Block ]
  29. writeable_objects = [ ]
  30. has_header = False
  31. is_streameable = False
  32. read_params = {
  33. Segment : [ ]
  34. }
  35. # do not supported write so no GUI stuff
  36. write_params = None
  37. name = 'NeuroScope'
  38. extensions = [ 'xml' ]
  39. mode = 'file'
  40. def __init__(self , filename = None) :
  41. """
  42. Arguments:
  43. filename : the filename
  44. """
  45. BaseIO.__init__(self)
  46. self.filename = filename
  47. def read_block(self,
  48. lazy = False,
  49. cascade = True,
  50. ):
  51. """
  52. """
  53. tree = ElementTree.parse(self.filename)
  54. root = tree.getroot()
  55. acq = root.find('acquisitionSystem')
  56. nbits = int(acq.find('nBits').text)
  57. nbchannel = int(acq.find('nChannels').text)
  58. sampling_rate = float(acq.find('samplingRate').text)*pq.Hz
  59. voltage_range = float(acq.find('voltageRange').text)
  60. #offset = int(acq.find('offset').text)
  61. amplification = float(acq.find('amplification').text)
  62. bl = Block(file_origin = os.path.basename(self.filename).replace('.xml', ''))
  63. if cascade:
  64. seg = Segment()
  65. bl.segments.append(seg)
  66. # RCG
  67. for i, xml_chx in enumerate(root.find('anatomicalDescription').find('channelGroups').findall('group')):
  68. n_channels = len(xml_chx)
  69. chx = ChannelIndex(name='Group {0}'.format(i),
  70. index=np.arange(n_channels, dtype = int))
  71. chx.channel_ids = np.array([int(xml_rc.text) for xml_rc in xml_chx])
  72. chx.channel_names = np.array(['Channel{0}'.format(id) for id in chx.channel_ids], dtype = 'S')
  73. bl.channel_indexes.append(chx)
  74. # AnalogSignals
  75. reader = RawBinarySignalIO(filename = self.filename.replace('.xml', '.dat'))
  76. seg2 = reader.read_segment(cascade = True, lazy = lazy,
  77. sampling_rate = sampling_rate,
  78. t_start = 0.*pq.s,
  79. unit = pq.V, nbchannel = nbchannel,
  80. bytesoffset = 0,
  81. dtype = np.int16 if nbits<=16 else np.int32,
  82. rangemin = -voltage_range/2.,
  83. rangemax = voltage_range/2.,)
  84. for s, sig in enumerate(seg2.analogsignals):
  85. if not lazy:
  86. sig /= amplification
  87. sig.segment = seg
  88. seg.analogsignals.append(sig)
  89. chx.analogsignals.append(sig)
  90. bl.create_many_to_one_relationship()
  91. return bl