@@ -24,9 +24,10 @@ class BiocamRawIO(BaseRawIO):
2424 >>> r.parse_header()
2525 >>> print(r)
2626 >>> raw_chunk = r.get_analogsignal_chunk(block_index=0, seg_index=0,
27- i_start=0, i_stop=1024, channel_names=channel_names)
28- >>> float_chunk = reader.rescale_signal_raw_to_float(raw_chunk, dtype='float64',
29- channel_indexes=[0, 3, 6])
27+ i_start=0, i_stop=1024,
28+ channel_names=channel_names)
29+ >>> float_chunk = r.rescale_signal_raw_to_float(raw_chunk, dtype='float64',
30+ channel_indexes=[0, 3, 6])
3031 """
3132 extensions = ['h5' ]
3233 rawmode = 'one-file'
@@ -53,7 +54,9 @@ def _parse_header(self):
5354 self ._sampling_rate = self ._header_dict ["sampling_rate" ]
5455 self ._filehandle = self ._header_dict ["file_handle" ]
5556 self ._read_function = self ._header_dict ["read_function" ]
56- self ._channel_locations - self ._header_dict ["locations" ]
57+ channel_locations = self ._header_dict ["locations" ]
58+ gain = self ._header_dict ["gain" ]
59+ offset = self ._header_dict ["offset" ]
5760
5861 signal_streams = np .array ([('Signals' , '0' )], dtype = _signal_stream_dtype )
5962
@@ -64,8 +67,8 @@ def _parse_header(self):
6467 sr = self ._sampling_rate # Hz
6568 dtype = "uint16"
6669 units = 'uV'
67- gain = 1. # TODO find gain
68- offset = 0. # TODO find offset
70+ gain = gain
71+ offset = offset
6972 stream_id = '0'
7073 sig_channels .append ((ch_name , chan_id , sr , dtype , units , gain , offset , stream_id ))
7174 sig_channels = np .array (sig_channels , dtype = _signal_channel_dtype )
@@ -75,18 +78,20 @@ def _parse_header(self):
7578 event_channels = np .array (event_channels , dtype = _event_channel_dtype )
7679
7780 # No spikes
78- unit_channels = []
79- unit_channels = np .array (unit_channels , dtype = _spike_channel_dtype )
81+ spike_channels = []
82+ spike_channels = np .array (spike_channels , dtype = _spike_channel_dtype )
8083
8184 self .header = {}
8285 self .header ['nb_block' ] = 1
8386 self .header ['nb_segment' ] = [1 ]
8487 self .header ['signal_streams' ] = signal_streams
8588 self .header ['signal_channels' ] = sig_channels
86- self .header ['unit_channels ' ] = unit_channels
89+ self .header ['spike_channels ' ] = spike_channels
8790 self .header ['event_channels' ] = event_channels
8891
8992 self ._generate_minimal_annotations ()
93+ stram_ann = self .raw_annotations ['blocks' ][0 ]['segments' ][0 ]['signals' ][0 ]
94+ stram_ann ['__array_annotations__' ]['location' ] = np .array (channel_locations )
9095
9196 def _segment_t_start (self , block_index , seg_index ):
9297 all_starts = [[0. ]]
@@ -113,7 +118,7 @@ def _get_analogsignal_chunk(self, block_index, seg_index, i_start, i_stop,
113118 i_stop = self ._num_frames
114119
115120 data = self ._read_function (self ._filehandle , i_start , i_stop , self ._num_channels )
116- return data [:, channel_indexes ]
121+ return np . squeeze ( data [:, channel_indexes ])
117122
118123
119124def open_biocam_file_header (filename , mea_pitch , verbose = False ):
@@ -128,79 +133,68 @@ def open_biocam_file_header(filename, mea_pitch, verbose=False):
128133
129134 rf = h5py .File (filename , 'r' )
130135 # Read recording variables
131- recVars = rf .require_group ('3BRecInfo/3BRecVars/' )
132- # bitDepth = recVars ['BitDepth'].value [0]
133- # maxV = recVars ['MaxVolt'].value [0]
134- # minV = recVars ['MinVolt'].value [0]
135- nFrames = recVars ['NRecFrames' ][0 ]
136- samplingRate = recVars ['SamplingRate' ][0 ]
137- signalInv = recVars ['SignalInversion' ][0 ]
136+ rec_vars = rf .require_group ('3BRecInfo/3BRecVars/' )
137+ bit_depth = rec_vars ['BitDepth' ][0 ]
138+ max_uv = rec_vars ['MaxVolt' ][0 ]
139+ min_uv = rec_vars ['MinVolt' ][0 ]
140+ n_frames = rec_vars ['NRecFrames' ][0 ]
141+ sampling_rate = rec_vars ['SamplingRate' ][0 ]
142+ signal_inv = rec_vars ['SignalInversion' ][0 ]
138143 # Read chip variables
139- chipVars = rf .require_group ('3BRecInfo/3BMeaChip/' )
140- nCols = chipVars ['NCols' ][0 ]
144+ chip_vars = rf .require_group ('3BRecInfo/3BMeaChip/' )
145+ n_cols = chip_vars ['NCols' ][0 ]
141146 # Get the actual number of channels used in the recording
142- file_format = rf ['3BData' ].attrs .get ('Version' )
147+ file_format = rf ['3BData' ].attrs .get ('Version' , None )
148+ format_100 = False
143149 if file_format == 100 :
144- nRecCh = len (rf ['3BData/Raw' ][0 ])
145- elif (file_format == 101 ) or (file_format == 102 ):
146- nRecCh = int (1. * rf ['3BData/Raw' ].shape [0 ] / nFrames )
150+ n_channels = len (rf ['3BData/Raw' ][0 ])
151+ format_100 = True
152+ elif file_format in (101 , 102 ) or file_format is None :
153+ n_channels = int (1. * rf ['3BData/Raw' ].shape [0 ] / n_frames )
147154 else :
148155 raise Exception ('Unknown data file format.' )
149156
150- if verbose :
151- print ('# 3Brain data format:' , file_format , 'signal inversion' , signalInv )
152- print ('# signal range: ' , recVars ['MinVolt' ][0 ], '- ' , recVars ['MaxVolt' ][0 ])
153- print ('# channels: ' , nRecCh )
154- print ('# frames: ' , nFrames )
155- print ('# sampling rate: ' , samplingRate )
156157 # get channel locations
157- r = (rf ['3BRecInfo/3BMeaStreams/Raw/Chs' ][()]['Row' ] - 1 ) * mea_pitch
158- c = (rf ['3BRecInfo/3BMeaStreams/Raw/Chs' ][()]['Col' ] - 1 ) * mea_pitch
159- rawIndices = np .vstack ((r , c )).T
158+ rows = (rf ['3BRecInfo/3BMeaStreams/Raw/Chs' ][()]['Row' ] - 1 ) * mea_pitch
159+ cols = (rf ['3BRecInfo/3BMeaStreams/Raw/Chs' ][()]['Col' ] - 1 ) * mea_pitch
160+ locations = np .vstack ((rows , cols )).T
160161 # assign channel numbers
161- chIndices = np .array ([(x - 1 ) + (y - 1 ) * nCols for (y , x ) in rawIndices ])
162+ ch_indices = np .array ([(x - 1 ) + (y - 1 ) * n_cols for (y , x ) in locations ])
162163 # determine correct function to read data
163- if verbose :
164- print ("# Signal inversion is " + str (signalInv ) + "." )
165- print ("# If your spike sorting results look wrong, invert the signal." )
166- if (file_format == 100 ) & (signalInv == 1 ):
167- read_function = readHDF5t_100
168- elif (file_format == 100 ) & (signalInv == - 1 ):
169- read_function = readHDF5t_100_i
170- if ((file_format == 101 ) | (file_format == 102 )) & (signalInv == 1 ):
171- read_function = readHDF5t_101
172- elif ((file_format == 101 ) | (file_format == 102 )) & (signalInv == - 1 ):
173- read_function = readHDF5t_101_i
164+ if format_100 :
165+ if signal_inv == 1 :
166+ read_function = readHDF5t_100
167+ elif signal_inv == 1 :
168+ read_function = readHDF5t_100_i
169+ else :
170+ raise Exception ("Unknown signal inversion" )
174171 else :
175- raise RuntimeError ("File format unknown." )
176- return dict (file_handle = rf , num_frames = nFrames , sampling_rate = samplingRate , num_channels = nRecCh ,
177- channel_inds = chIndices , file_format = file_format , signal_inv = signalInv ,
178- locations = rawIndices , read_function = read_function )
172+ if signal_inv == 1 :
173+ read_function = readHDF5t_101
174+ elif signal_inv == 1 :
175+ read_function = readHDF5t_101_i
176+ else :
177+ raise Exception ("Unknown signal inversion" )
178+
179+ gain = (max_uv - min_uv ) / (2 ** bit_depth )
180+ offset = min_uv
181+
182+ return dict (file_handle = rf , num_frames = n_frames , sampling_rate = sampling_rate , num_channels = n_channels ,
183+ channel_inds = ch_indices , file_format = file_format , signal_inv = signal_inv ,
184+ locations = locations , read_function = read_function , gain = gain , offset = offset )
179185
180186
181187def readHDF5t_100 (rf , t0 , t1 , nch ):
182- if t0 <= t1 :
183- return rf ['3BData/Raw' ][t0 :t1 ]
184- else : # Reversed read
185- raise Exception ('Reading backwards? Not sure about this.' )
188+ return rf ['3BData/Raw' ][t0 :t1 ]
186189
187190
188191def readHDF5t_100_i (rf , t0 , t1 , nch ):
189- if t0 <= t1 :
190- return 4096 - rf ['3BData/Raw' ][t0 :t1 ]
191- else : # Reversed read
192- raise Exception ('Reading backwards? Not sure about this.' )
192+ return 4096 - rf ['3BData/Raw' ][t0 :t1 ]
193193
194194
195195def readHDF5t_101 (rf , t0 , t1 , nch ):
196- if t0 <= t1 :
197- return rf ['3BData/Raw' ][nch * t0 :nch * t1 ].reshape ((t1 - t0 , nch ), order = 'C' )
198- else : # Reversed read
199- raise Exception ('Reading backwards? Not sure about this.' )
196+ return rf ['3BData/Raw' ][nch * t0 :nch * t1 ].reshape ((t1 - t0 , nch ), order = 'C' )
200197
201198
202199def readHDF5t_101_i (rf , t0 , t1 , nch ):
203- if t0 <= t1 :
204- return 4096 - rf ['3BData/Raw' ][nch * t0 :nch * t1 ].reshape ((t1 - t0 , nch ), order = 'C' )
205- else : # Reversed read
206- raise Exception ('Reading backwards? Not sure about this.' )
200+ return 4096 - rf ['3BData/Raw' ][nch * t0 :nch * t1 ].reshape ((t1 - t0 , nch ), order = 'C' )
0 commit comments