@@ -134,31 +134,38 @@ def read_block(self, block_index=0, lazy=False,
134134
135135 bl = Block (** bl_annotations )
136136
137- # Group for AnalogSignals
137+ # Group for AnalogSignals come from signal_streams
138138 if create_group_across_segment ['AnalogSignal' ]:
139- all_channels = self .header ['signal_channels' ]
140- channel_indexes_list = self .get_group_signal_channel_indexes ()
141- sig_groups = []
142- for channel_index in channel_indexes_list :
143- for i , (ind_within , ind_abs ) in self ._make_signal_channel_subgroups (
144- channel_index , signal_group_mode = signal_group_mode ).items ():
145- group = Group (name = 'AnalogSignal group {}' .format (i ))
146- # @andrew @ julia @michael : do we annotate group across segment with this arrays ?
147- group .annotate (ch_names = all_channels [ind_abs ]['name' ].astype ('U' )) # ??
148- group .annotate (channel_ids = all_channels [ind_abs ]['id' ]) # ??
149- bl .groups .append (group )
150- sig_groups .append (group )
139+ #~ all_channels = self.header['signal_channels']
140+ #~ channel_indexes_list = self.get_group_signal_channel_indexes()
141+ #~ sig_groups = []
142+ #~ for channel_index in channel_indexes_list:
143+ #~ for i, (ind_within, ind_abs) in self._make_signal_channel_subgroups(
144+ #~ channel_index, signal_group_mode=signal_group_mode).items():
145+ #~ group = Group(name='AnalogSignal group {}'.format(i))
146+ #~ # @andrew @ julia @michael : do we annotate group across segment with this arrays ?
147+ #~ group.annotate(ch_names=all_channels[ind_abs]['name'].astype('U')) # ??
148+ #~ group.annotate(channel_ids=all_channels[ind_abs]['id']) # ??
149+ #~ bl.groups.append(group)
150+ #~ sig_groups.append(group)
151+
152+ signal_streams = self .header ['signal_streams' ]
153+ sub_streams = self .get_sub_signal_streams (signal_group_mode )
154+ sub_stream_groups = []
155+ for sub_stream in sub_streams :
156+ stream_index , inner_stream_channels , name = sub_stream
157+ group = Group (name = name ,
158+ stream_id = signal_streams [stream_index ]['id' ])
159+ bl .groups .append (group )
160+ sub_stream_groups .append (group )
151161
152162 if create_group_across_segment ['SpikeTrain' ]:
153- unit_channels = self .header ['unit_channels ' ]
163+ spike_channels = self .header ['spike_channels ' ]
154164 st_groups = []
155- for c in range (unit_channels .size ):
165+ for c in range (spike_channels .size ):
156166 group = Group (name = 'SpikeTrain group {}' .format (c ))
157- group .annotate (unit_name = unit_channels [c ]['name' ])
158- group .annotate (unit_id = unit_channels [c ]['id' ])
159- unit_annotations = self .raw_annotations ['unit_channels' ][c ]
160- unit_annotations = check_annotations (unit_annotations )
161- group .annotate (** unit_annotations )
167+ group .annotate (unit_name = spike_channels [c ]['name' ])
168+ group .annotate (unit_id = spike_channels [c ]['id' ])
162169 bl .groups .append (group )
163170 st_groups .append (group )
164171
@@ -183,7 +190,7 @@ def read_block(self, block_index=0, lazy=False,
183190 for seg in bl .segments :
184191 if create_group_across_segment ['AnalogSignal' ]:
185192 for c , anasig in enumerate (seg .analogsignals ):
186- sig_groups [c ].add (anasig )
193+ sub_stream_groups [c ].add (anasig )
187194
188195 if create_group_across_segment ['SpikeTrain' ]:
189196 for c , sptr in enumerate (seg .spiketrains ):
@@ -231,38 +238,67 @@ def read_segment(self, block_index=0, seg_index=0, lazy=False,
231238 signal_group_mode = self ._prefered_signal_group_mode
232239
233240 # annotations
234- seg_annotations = dict ( self .raw_annotations ['blocks' ][block_index ]['segments' ][seg_index ])
235- for k in ('signals' , 'units ' , 'events' ):
241+ seg_annotations = self .raw_annotations ['blocks' ][block_index ]['segments' ][seg_index ]. copy ( )
242+ for k in ('signals' , 'spikes ' , 'events' ):
236243 seg_annotations .pop (k )
237244 seg_annotations = check_annotations (seg_annotations )
238245
239246 seg = Segment (index = seg_index , ** seg_annotations )
240247
241248 # AnalogSignal
242- signal_channels = self .header ['signal_channels' ]
243- if signal_channels .size > 0 :
244- channel_indexes_list = self .get_group_signal_channel_indexes ()
245- for channel_indexes in channel_indexes_list :
246- for i , (ind_within , ind_abs ) in self ._make_signal_channel_subgroups (
247- channel_indexes ,
248- signal_group_mode = signal_group_mode ).items ():
249- # make a proxy...
250- anasig = AnalogSignalProxy (rawio = self , global_channel_indexes = ind_abs ,
251- block_index = block_index , seg_index = seg_index )
252-
253- if not lazy :
254- # ... and get the real AnalogSIgnal if not lazy
255- anasig = anasig .load (time_slice = time_slice , strict_slicing = strict_slicing )
256- # TODO magnitude_mode='rescaled'/'raw'
257-
258- anasig .segment = seg
259- seg .analogsignals .append (anasig )
249+ #~ signal_channels = self.header['signal_channels']
250+ #~ if signal_channels.size > 0:
251+ #~ channel_indexes_list = self.get_group_signal_channel_indexes()
252+ #~ for channel_indexes in channel_indexes_list:
253+ #~ for i, (ind_within, ind_abs) in self._make_signal_channel_subgroups(
254+ #~ channel_indexes,
255+ #~ signal_group_mode=signal_group_mode).items():
256+ #~ # make a proxy...
257+ #~ anasig = AnalogSignalProxy(rawio=self, global_channel_indexes=ind_abs,
258+ #~ block_index=block_index, seg_index=seg_index)
259+
260+ #~ if not lazy:
261+ #~ # ... and get the real AnalogSIgnal if not lazy
262+ #~ anasig = anasig.load(time_slice=time_slice, strict_slicing=strict_slicing)
263+ #~ # TODO magnitude_mode='rescaled'/'raw'
264+
265+ #~ anasig.segment = seg
266+ #~ seg.analogsignals.append(anasig)
267+
268+ # AnalogSignal
269+ #~ signal_streams = self.header['signal_streams']
270+ #~ for stream_index in range(len(signal_streams)):
271+ #~ anasig = AnalogSignalProxy(rawio=self, stream_index=stream_index,
272+ #~ block_index=block_index, seg_index=seg_index)
273+ #~ if not lazy:
274+ #~ # ... and get the real AnalogSIgnal if not lazy
275+ #~ anasig = anasig.load(time_slice=time_slice, strict_slicing=strict_slicing)
276+
277+ #~ anasig.segment = seg
278+ #~ seg.analogsignals.append(anasig)
279+ signal_streams = self .header ['signal_streams' ]
280+ sub_streams = self .get_sub_signal_streams (signal_group_mode )
281+ for sub_stream in sub_streams :
282+ stream_index , inner_stream_channels , name = sub_stream
283+ anasig = AnalogSignalProxy (rawio = self , stream_index = stream_index ,
284+ inner_stream_channels = inner_stream_channels ,
285+ block_index = block_index , seg_index = seg_index )
286+ anasig .name = name
287+
288+ if not lazy :
289+ # ... and get the real AnalogSIgnal if not lazy
290+ anasig = anasig .load (time_slice = time_slice , strict_slicing = strict_slicing )
291+
292+ anasig .segment = seg
293+ seg .analogsignals .append (anasig )
294+
295+
260296
261297 # SpikeTrain and waveforms (optional)
262- unit_channels = self .header ['unit_channels ' ]
263- for unit_index in range (len (unit_channels )):
298+ spike_channels = self .header ['spike_channels ' ]
299+ for spike_channel_index in range (len (spike_channels )):
264300 # make a proxy...
265- sptr = SpikeTrainProxy (rawio = self , unit_index = unit_index ,
301+ sptr = SpikeTrainProxy (rawio = self , spike_channel_index = spike_channel_index ,
266302 block_index = block_index , seg_index = seg_index )
267303
268304 if not lazy :
@@ -295,37 +331,92 @@ def read_segment(self, block_index=0, seg_index=0, lazy=False,
295331 seg .create_many_to_one_relationship ()
296332 return seg
297333
298- def _make_signal_channel_subgroups (self , channel_indexes ,
299- signal_group_mode = 'group-by-same-units' ):
334+ def get_sub_signal_streams (self , signal_group_mode = 'group-by-same-units' ):
300335 """
301- For some RawIO channel are already splitted in groups.
302- But in any cases, channel need to be splitted again in sub groups
303- because they do not have the same units.
304-
305- They can also be splitted one by one to match previous behavior for
306- some IOs in older version of neo (<=0.5).
307-
308- This method aggregate signal channels with same units or split them all.
336+ When a signal streams don't have homogeneous si units accros channels.
337+ They have to be splitted in sub streams to construct AnalogSignal (unique units).
338+
339+ They function also help to split each channel into one AnalogSignal like in
340+ old neo (<=0.5).
341+
309342 """
310- all_channels = self .header ['signal_channels' ]
311- if channel_indexes is None :
312- channel_indexes = np .arange (all_channels .size , dtype = int )
313- channels = all_channels [channel_indexes ]
314-
315- groups = collections .OrderedDict ()
316- if signal_group_mode == 'group-by-same-units' :
317- all_units = np .unique (channels ['units' ])
318-
319- for i , unit in enumerate (all_units ):
320- ind_within , = np .nonzero (channels ['units' ] == unit )
321- ind_abs = channel_indexes [ind_within ]
322- groups [i ] = (ind_within , ind_abs )
323-
324- elif signal_group_mode == 'split-all' :
325- for i , chan_index in enumerate (channel_indexes ):
326- ind_within = [i ]
327- ind_abs = channel_indexes [ind_within ]
328- groups [i ] = (ind_within , ind_abs )
329- else :
330- raise (NotImplementedError )
331- return groups
343+ signal_streams = self .header ['signal_streams' ]
344+ signal_channels = self .header ['signal_channels' ]
345+
346+ sub_streams = []
347+ for stream_index in range (len (signal_streams )):
348+ stream_id = signal_streams [stream_index ]['id' ]
349+ stream_name = signal_streams [stream_index ]['name' ]
350+ mask = signal_channels ['stream_id' ] == stream_id
351+ channels = signal_channels [mask ]
352+ if signal_group_mode == 'group-by-same-units' :
353+ # standard behavior
354+
355+ ## this do not keep the original order
356+ ## all_units = np.unique(channels['units'])
357+ # so python loop
358+ all_units = []
359+ for units in channels ['units' ]:
360+ if units not in all_units :
361+ all_units .append (units )
362+
363+ if len (all_units ) == 1 :
364+ #no substream
365+ inner_stream_channels = None # None iwill be transform as slice later
366+ name = stream_name
367+ sub_stream = (stream_index , inner_stream_channels , name )
368+ sub_streams .append (sub_stream )
369+ else :
370+ for units in all_units :
371+ inner_stream_channels , = np .nonzero (channels ['units' ] == units )
372+ chan_names = channels [inner_stream_channels ]['name' ]
373+ name = 'Channels: (' + ' ' .join (chan_names ) + ')'
374+ sub_stream = (stream_index , inner_stream_channels , name )
375+ sub_streams .append (sub_stream )
376+ elif signal_group_mode == 'split-all' :
377+ # mimic all neo <= 0.5 behavior
378+ for i , channel in enumerate (channels ):
379+ inner_stream_channels = [i ]
380+ name = channels [i ]['name' ]
381+ sub_stream = (stream_index , inner_stream_channels , name )
382+ sub_streams .append (sub_stream )
383+ else :
384+ raise (NotImplementedError )
385+
386+ return sub_streams
387+
388+
389+ #~ def _make_signal_channel_subgroups(self, channel_indexes,
390+ #~ signal_group_mode='group-by-same-units'):
391+ #~ """
392+ #~ For some RawIO channel are already splitted in groups.
393+ #~ But in any cases, channel need to be splitted again in sub groups
394+ #~ because they do not have the same units.
395+
396+ #~ They can also be splitted one by one to match previous behavior for
397+ #~ some IOs in older version of neo (<=0.5).
398+
399+ #~ This method aggregate signal channels with same units or split them all.
400+ #~ """
401+ #~ all_channels = self.header['signal_channels']
402+ #~ if channel_indexes is None:
403+ #~ channel_indexes = np.arange(all_channels.size, dtype=int)
404+ #~ channels = all_channels[channel_indexes]
405+
406+ #~ groups = collections.OrderedDict()
407+ #~ if signal_group_mode == 'group-by-same-units':
408+ #~ all_units = np.unique(channels['units'])
409+
410+ #~ for i, unit in enumerate(all_units):
411+ #~ ind_within, = np.nonzero(channels['units'] == unit)
412+ #~ ind_abs = channel_indexes[ind_within]
413+ #~ groups[i] = (ind_within, ind_abs)
414+
415+ #~ elif signal_group_mode == 'split-all':
416+ #~ for i, chan_index in enumerate(channel_indexes):
417+ #~ ind_within = [i]
418+ #~ ind_abs = channel_indexes[ind_within]
419+ #~ groups[i] = (ind_within, ind_abs)
420+ #~ else:
421+ #~ raise (NotImplementedError)
422+ #~ return groups
0 commit comments