Repository: NeuralEnsemble/python-neo

Issue:
Hitting Spike2IO asserion on sampling_rate
I'm trying to import a spike2 smr file using `Spike2IO(filename=filename)` but am hitting an assertion:

```
Traceback (most recent call last):
  File "G:/Python/libs/Playground/src/playground2.py", line 3, in <module>
    reader = Spike2IO(filename=r'G:\Python\1-9-2018-mouse-left-odor mixture-10 trials.smr')
  File "E:\Python\Python35-x64\lib\site-packages\neo\io\spike2io.py", line 10, in __init__
    BaseFromRaw.__init__(self, filename)
  File "E:\Python\Python35-x64\lib\site-packages\neo\io\basefromrawio.py", line 71, in __init__
    self.parse_header()
  File "E:\Python\Python35-x64\lib\site-packages\neo\rawio\baserawio.py", line 155, in parse_header
    self._parse_header()
  File "E:\Python\Python35-x64\lib\site-packages\neo\rawio\spike2rawio.py", line 199, in _parse_header
    assert sampling_rate.size==1
AssertionError
```

So I printed the value of `sampling_rate` and it's `[ 1000.  2000. 10000.]`. Is it unable to use channels with different sampling rates?

Discussion:

Patch:
diff --git a/neo/io/spike2io.py b/neo/io/spike2io.py
index 405f98f0..d21f3fc4 100644
--- a/neo/io/spike2io.py
+++ b/neo/io/spike2io.py
@@ -5,7 +5,7 @@ from neo.rawio.spike2rawio import Spike2RawIO
 
 
 class Spike2IO(Spike2RawIO, BaseFromRaw):
-    _prefered_signal_group_mode = 'split-all'
+    _prefered_signal_group_mode = 'group-by-same-units'
 
     def __init__(self, filename):
         Spike2RawIO.__init__(self, filename=filename)
diff --git a/neo/rawio/spike2rawio.py b/neo/rawio/spike2rawio.py
index f14b1f60..08ef148a 100644
--- a/neo/rawio/spike2rawio.py
+++ b/neo/rawio/spike2rawio.py
@@ -53,6 +53,8 @@ class Spike2RawIO(BaseRawIO):
                 info['datetime_detail'] = 0
                 info['datetime_year'] = 0
 
+            self._time_factor = info['us_per_time'] * info['dtime_base']
+
             self._channel_infos = []
             for chan_id in range(info['channels']):
                 fid.seek(512 + 140 * chan_id)
@@ -88,36 +90,106 @@ class Spike2RawIO(BaseRawIO):
 
                 self._channel_infos.append(chan_info)
 
-        # get data blocks index
+        # get data blocks index for all channel
+        # run through all data block of of channel to prepare chan to block maps
         self._memmap = np.memmap(self.filename, dtype='u1', offset=0, mode='r')
-        self._data_blocks = []
+        self._all_data_blocks = {}
+        self._by_seg_data_blocks = {}
         for c, chan_info in enumerate(self._channel_infos):
             data_blocks = []
             ind = chan_info['firstblock']
             for b in range(chan_info['blocks']):
-
                 block_info = self._memmap[ind:ind + 20].view(blockHeaderDesciption)[0]
-                data_blocks.append((ind, block_info['items'], 0))
+                data_blocks.append((ind, block_info['items'], 0, 
+                            block_info['start_time'], block_info['end_time']))
                 ind = block_info['succ_block']
 
             data_blocks = np.array(data_blocks, dtype=[(
-                'pos', 'int32'), ('size', 'int32'), ('cumsum', 'int32')])
-            data_blocks['cumsum'][1:] = np.cumsum(data_blocks['size'][:-1])
-
+                'pos', 'int32'), ('size', 'int32'), ('cumsum', 'int32'),
+                ('start_time', 'int32'), ('end_time', 'int32')])
             data_blocks['pos'] += 20  # 20 is ths header size
 
-            self._data_blocks.append(data_blocks)
-
+            self._all_data_blocks[c] = data_blocks
+            self._by_seg_data_blocks[c] = []
+        
+        # For all signal channel detect gaps between data block (pause in rec) so new Segment.
+        # then check that all channel have the same gaps.
+        # this part is tricky because we need to check that all channel have same pause.
+        all_gaps_block_ind = {}
+        for c, chan_info in enumerate(self._channel_infos):
+            if chan_info['kind'] in [1, 9]:
+                data_blocks = self._all_data_blocks[c]
+                sig_size = np.sum(self._all_data_blocks[chan_id]['size'])
+                if sig_size>0:
+                    sample_interval = chan_info['divide'] * info['time_per_adc']
+                    # detect gaps
+                    inter_block_sizes = data_blocks['start_time'][1:] - data_blocks['end_time'][:-1]
+                    gaps_block_ind, = np.nonzero(inter_block_sizes>sample_interval)
+                    all_gaps_block_ind[c] = gaps_block_ind
+
+        # find t_start/t_stop for each seg based on gaps indexe
+        self._sig_t_starts = {}
+        self._sig_t_stops = {}
+        if len(all_gaps_block_ind) == 0:
+            # this means no signal channels
+            nb_segment = 1
+            # loop over event/spike channel to get the min/max time
+            t_start, t_stop = None, None
+            for chan_id, chan_info in enumerate(self._channel_infos):
+                data_blocks = self._all_data_blocks[chan_id]
+                if data_blocks.size > 0:
+                    # if t_start is None or data_blocks[0]['start_time']<t_start:
+                        # t_start = data_blocks[0]['start_time']
+                    if t_stop is None or data_blocks[-1]['end_time']>t_stop:
+                        t_stop = data_blocks[-1]['end_time']
+            # self._seg_t_starts = [t_start]
+            self._seg_t_starts = [0]
+            self._seg_t_stops = [t_stop]
+        else:
+            all_nb_seg = np.array([v.size+1 for v in all_gaps_block_ind.values()])
+            assert np.all(all_nb_seg[0]==all_nb_seg), \
+                            'Signal channel have differents pause so diffrents nb_segment'
+            nb_segment = int(all_nb_seg[0])
+            
+            for chan_id, gaps_block_ind in all_gaps_block_ind.items():
+                data_blocks = self._all_data_blocks[chan_id]
+                self._sig_t_starts[chan_id] = []
+                self._sig_t_stops[chan_id] = []
+                
+                for seg_ind in range(nb_segment):
+                    if seg_ind==0:
+                        fisrt_bl = 0
+                    else:
+                        fisrt_bl = gaps_block_ind[seg_ind-1] + 1
+                    self._sig_t_starts[chan_id].append(data_blocks[fisrt_bl]['start_time'])
+                    
+                    if seg_ind<nb_segment-1:
+                        last_bl = gaps_block_ind[seg_ind]
+                    else:
+                        last_bl = data_blocks.size - 1
+                    
+                    self._sig_t_stops[chan_id].append(data_blocks[last_bl]['end_time'])
+                    
+                    in_seg_data_block = data_blocks[fisrt_bl:last_bl+1]
+                    in_seg_data_block['cumsum'][1:] = np.cumsum(in_seg_data_block['size'][:-1])
+                    self._by_seg_data_blocks[chan_id].append(in_seg_data_block)
+            
+            self._seg_t_starts = []
+            self._seg_t_stops = []
+            for seg_ind in range(nb_segment):
+                # there is a small delay between all channel so take the max/min for t_start/t_stop
+                t_start = min(self._sig_t_starts[chan_id][seg_ind] for chan_id in self._sig_t_starts)
+                t_stop = max(self._sig_t_stops[chan_id][seg_ind] for chan_id in self._sig_t_stops)
+                self._seg_t_starts.append(t_start)
+                self._seg_t_stops.append(t_stop)
+        
         # create typed channels
         sig_channels = []
         unit_channels = []
         event_channels = []
 
-        all_signal_length = []  # this is incredible but shape difer channel to channel!!!
         self.internal_unit_ids = {}
-        self._spike_sounts = {}
         for chan_id, chan_info in enumerate(self._channel_infos):
-
             if chan_info['kind'] in [1, 6, 7, 9]:
                 if self.take_ideal_sampling_rate:
                     sampling_rate = info['ideal_rate']
@@ -134,8 +206,7 @@ class Spike2RawIO(BaseRawIO):
 
             if chan_info['kind'] in [1, 9]:
                 # AnalogSignal
-                sig_size = np.sum(self._data_blocks[chan_id]['size'])
-                if sig_size == 0:
+                if chan_id not in self._sig_t_starts:
                     continue
                 units = chan_info['unit']
                 if chan_info['kind'] == 1:  # int16
@@ -150,8 +221,6 @@ class Spike2RawIO(BaseRawIO):
                 sig_channels.append((name, chan_id, sampling_rate, sig_dtype,
                                      units, gain, offset, group_id))
 
-                all_signal_length.append(sig_size)
-
             elif chan_info['kind'] in [2, 3, 4, 5, 8]:
                 # Event
                 event_channels.append((name, chan_id, 'event'))
@@ -170,76 +239,41 @@ class Spike2RawIO(BaseRawIO):
                 if self.ced_units:
                     # this is a hudge pain because need
                     # to jump over all blocks
-                    nb_spike_by_ids = {}
-                    data_blocks = self._data_blocks[chan_id]
+                    data_blocks = self._all_data_blocks[chan_id]
                     dt = get_channel_dtype(chan_info)
+                    unit_ids = set()
                     for bl in range(data_blocks.size):
                         ind0 = data_blocks[bl]['pos']
                         ind1 = data_blocks[bl]['size'] * dt.itemsize + ind0
                         raw_data = self._memmap[ind0:ind1].view(dt)
                         marker = raw_data['marker'] & 255
-                        for unit_id in np.unique(marker):
-                            nb_spike = nb_spike_by_ids.get(unit_id, 0)
-                            nb_spike += np.sum(marker == unit_id)
-                            nb_spike_by_ids[unit_id] = nb_spike
+                        unit_ids.update(np.unique(marker))
+                    unit_ids = sorted(list(unit_ids))
                 else:
                     # All spike from one channel are group in one SpikeTrain
-                    nb_spike_by_ids = {'all': data_blocks['size'].sum()}
-                for unit_id in sorted(nb_spike_by_ids.keys()):
+                    unit_ids = ['all']
+                for unit_id in unit_ids:
                     unit_index = len(unit_channels)
                     self.internal_unit_ids[unit_index] = (chan_id, unit_id)
-                    self._spike_sounts[unit_index] = nb_spike_by_ids[unit_id]
                     _id = "ch{}#{}".format(chan_id, unit_id)
                     unit_channels.append((name, _id, wf_units, wf_gain, wf_offset,
                                           wf_left_sweep, wf_sampling_rate))
-
+        
         sig_channels = np.array(sig_channels, dtype=_signal_channel_dtype)
-        print(sig_channels)
         unit_channels = np.array(unit_channels, dtype=_unit_channel_dtype)
         event_channels = np.array(event_channels, dtype=_event_channel_dtype)
-
-        if len(sig_channels) > 0:
-            sampling_rate = np.unique(sig_channels['sampling_rate'])
-            assert sampling_rate.size == 1
-            self._sampling_rate = float(sampling_rate[0])
-            self._signal_length = min(all_signal_length)
-
-            all_kind = [self._channel_infos[chan_id]['kind'] for chan_id in sig_channels['id']]
-            all_kind = np.unique(all_kind)
-            assert all_kind.size == 1, 'IO only support when all channel have the same dtype'
-
-            if all_kind[0] == 1:
-                self._sig_dtype = np.dtype('int16')
-            elif all_kind[0] == 9:
-                self._sig_dtype = np.dtype('float32')
-
-        self._time_factor = self._global_info['us_per_time'] * self._global_info['dtime_base']
-
-        # t_stop: best between events, spikes and signals
+        
         if len(sig_channels) > 0:
-            t_stop_sig = self._signal_length / self._sampling_rate
-        else:
-            t_stop_sig = 0.
-
-        t_stop_ev = 0.
-        for chan_id, chan_info in enumerate(self._channel_infos):
-            if chan_info['kind'] in [1, 9, 0]:
-                continue
-            data_blocks = self._data_blocks[chan_id]
-            if data_blocks.size > 0:
-                dt = get_channel_dtype(chan_info)
-                ind0 = data_blocks[-1]['pos']
-                ind1 = data_blocks[-1]['size'] * dt.itemsize + ind0
-                raw_data = self._memmap[ind0:ind1].view(dt)
-                last_time = raw_data['tick'][-1] * self._time_factor
-                if last_time > t_stop_ev:
-                    t_stop_ev = last_time
-        self._t_stop = max(t_stop_sig, t_stop_ev)
-
+            # signal channel can different sampling_rate/dtype/t_start/signal_length...
+            # grouping them is difficults, so each channe = one group
+            
+            sig_channels['group_id'] = np.arange(sig_channels.size)
+            self._sig_dtypes = {s['group_id']: np.dtype(s['dtype']) for s in sig_channels}
+            
         # fille into header dict
         self.header = {}
         self.header['nb_block'] = 1
-        self.header['nb_segment'] = [1]
+        self.header['nb_segment'] = [nb_segment]
         self.header['signal_channels'] = sig_channels
         self.header['unit_channels'] = unit_channels
         self.header['event_channels'] = event_channels
@@ -273,26 +307,33 @@ class Spike2RawIO(BaseRawIO):
         return self.filename
 
     def _segment_t_start(self, block_index, seg_index):
-        return 0.
+        return self._seg_t_starts[seg_index] * self._time_factor
 
     def _segment_t_stop(self, block_index, seg_index):
-        return self._t_stop
+        return self._seg_t_stops[seg_index] * self._time_factor
 
     def _get_signal_size(self, block_index, seg_index, channel_indexes):
-        return self._signal_length
+        assert len(channel_indexes) == 1
+        chan_id = self.header['signal_channels'][channel_indexes[0]]['id']
+        sig_size = np.sum(self._by_seg_data_blocks[chan_id][seg_index]['size'])
+        return sig_size
 
     def _get_signal_t_start(self, block_index, seg_index, channel_indexes):
-        return 0.
+        assert len(channel_indexes) == 1
+        chan_id = self.header['signal_channels'][channel_indexes[0]]['id']
+        return self._sig_t_starts[chan_id][seg_index] * self._time_factor
 
     def _get_analogsignal_chunk(self, block_index, seg_index,  i_start, i_stop, channel_indexes):
         if i_start is None:
             i_start = 0
         if i_stop is None:
-            i_stop = self._signal_length
+            i_stop = self._get_signal_size(block_index, seg_index, channel_indexes)
 
-        dt = self._sig_dtype
-        if channel_indexes is None:
-            channel_indexes = np.arange(self.header['signal_channels'].size)
+        assert len(channel_indexes) == 1
+        chan_index = channel_indexes[0]
+        chan_id = self.header['signal_channels'][chan_index]['id']
+        group_id = self.header['signal_channels'][channel_indexes[0]]['group_id']
+        dt = self._sig_dtypes[group_id]
 
         raw_signals = np.zeros((i_stop - i_start, len(channel_indexes)), dtype=dt)
         for c, channel_index in enumerate(channel_indexes):
@@ -302,7 +343,7 @@ class Spike2RawIO(BaseRawIO):
             # indexes. So this make the job too difficult.
             chan_header = self.header['signal_channels'][channel_index]
             chan_id = chan_header['id']
-            data_blocks = self._data_blocks[chan_id]
+            data_blocks = self._by_seg_data_blocks[chan_id][seg_index]
 
             # loop over data blocks and get chunks
             bl0 = np.searchsorted(data_blocks['cumsum'], i_start, side='left')
@@ -316,28 +357,52 @@ class Spike2RawIO(BaseRawIO):
                     # right border
                     # be carfull that bl could be both bl0 and bl1!!
                     border = data.size - (i_stop - data_blocks[bl]['cumsum'])
-                    data = data[:-border]
+                    if border>0:
+                        data = data[:-border]
                 if bl == bl0:
                     # left border
                     border = i_start - data_blocks[bl]['cumsum']
                     data = data[border:]
                 raw_signals[ind:data.size + ind, c] = data
                 ind += data.size
-
         return raw_signals
-
-    def _get_internal_timestamp_(self, chan_id, t_start, t_stop, other_field=None, marker_filter=None):
+    
+    def _count_in_time_slice(self, seg_index, chan_id, lim0, lim1, marker_filter=None):
+        # count event or spike in time slice
+        data_blocks = self._all_data_blocks[chan_id]
+        chan_info = self._channel_infos[chan_id]
+        dt = get_channel_dtype(chan_info)
+        nb = 0
+        for bl in range(data_blocks.size):
+            ind0 = data_blocks[bl]['pos']
+            ind1 = data_blocks[bl]['size'] * dt.itemsize + ind0
+            raw_data = self._memmap[ind0:ind1].view(dt)
+            ts = raw_data['tick']
+            keep = (ts >= lim0) & (ts <= lim1)
+            if marker_filter is not None:
+                keep2 = (raw_data['marker'] & 255) == marker_filter
+                keep = keep & keep2
+            nb += np.sum(keep)
+            if ts[-1] > lim1:
+                break
+        return nb
+    
+    def _get_internal_timestamp_(self, seg_index, chan_id, 
+                                t_start, t_stop, other_field=None, marker_filter=None):
         chan_info = self._channel_infos[chan_id]
-        data_blocks = self._data_blocks[chan_id]
+        # data_blocks = self._by_seg_data_blocks[chan_id][seg_index]
+        data_blocks = self._all_data_blocks[chan_id]
         dt = get_channel_dtype(chan_info)
 
         if t_start is None:
-            lim0 = 0
+            # lim0 = 0
+            lim0 = self._seg_t_starts[seg_index]
         else:
             lim0 = int(t_start / self._time_factor)
 
         if t_stop is None:
-            lim1 = 2**32
+            # lim1 = 2**32
+            lim1 = self._seg_t_stops[seg_index]
         else:
             lim1 = int(t_stop / self._time_factor)
 
@@ -374,7 +439,15 @@ class Spike2RawIO(BaseRawIO):
             return timestamps, othervalues
 
     def _spike_count(self,  block_index, seg_index, unit_index):
-        return self._spike_sounts[unit_index]
+        chan_id, unit_id = self.internal_unit_ids[unit_index]
+        if self.ced_units:
+            marker_filter = unit_id
+        else:
+            marker_filter = None        
+        lim0 = self._seg_t_starts[seg_index]
+        lim1 = self._seg_t_stops[seg_index]
+        return self._count_in_time_slice(seg_index, chan_id,
+                                        lim0, lim1, marker_filter=marker_filter)
 
     def _get_spike_timestamps(self,  block_index, seg_index, unit_index, t_start, t_stop):
         unit_header = self.header['unit_channels'][unit_index]
@@ -385,7 +458,7 @@ class Spike2RawIO(BaseRawIO):
         else:
             marker_filter = None
 
-        spike_timestamps = self._get_internal_timestamp_(
+        spike_timestamps = self._get_internal_timestamp_(seg_index,
             chan_id, t_start, t_stop, marker_filter=marker_filter)
 
         return spike_timestamps
@@ -404,8 +477,8 @@ class Spike2RawIO(BaseRawIO):
         else:
             marker_filter = None
 
-        timestamps, waveforms = self._get_internal_timestamp_(chan_id, t_start, t_stop,
-                                                              other_field='waveform', marker_filter=marker_filter)
+        timestamps, waveforms = self._get_internal_timestamp_(seg_index, chan_id, 
+                                        t_start, t_stop, other_field='waveform', marker_filter=marker_filter)
 
         waveforms = waveforms.reshape(timestamps.size, 1, -1)
 
@@ -414,9 +487,9 @@ class Spike2RawIO(BaseRawIO):
     def _event_count(self, block_index, seg_index, event_channel_index):
         event_header = self.header['event_channels'][event_channel_index]
         chan_id = int(event_header['id'])  # because set to string in header
-        data_blocks = self._data_blocks[chan_id]
-        nb_event = data_blocks['size'].sum()
-        return nb_event
+        lim0 = self._seg_t_starts[seg_index]
+        lim1 = self._seg_t_stops[seg_index]
+        return self._count_in_time_slice(seg_index, chan_id, lim0, lim1, marker_filter=None)
 
     def _get_event_timestamps(self,  block_index, seg_index, event_channel_index, t_start, t_stop):
         event_header = self.header['event_channels'][event_channel_index]
@@ -424,13 +497,14 @@ class Spike2RawIO(BaseRawIO):
         chan_info = self._channel_infos[chan_id]
 
         if chan_info['kind'] == 5:
-            timestamps, labels = self._get_internal_timestamp_(
+            timestamps, labels = self._get_internal_timestamp_(seg_index,
                 chan_id, t_start, t_stop, other_field='marker')
         elif chan_info['kind'] == 8:
-            timestamps, labels = self._get_internal_timestamp_(
+            timestamps, labels = self._get_internal_timestamp_(seg_index,
                 chan_id, t_start, t_stop, other_field='label')
         else:
-            timestamps = self._get_internal_timestamp_(chan_id, t_start, t_stop, other_field=None)
+            timestamps = self._get_internal_timestamp_(seg_index,
+                                    chan_id, t_start, t_stop, other_field=None)
             labels = np.zeros(timestamps.size, dtype='U')
 
         labels = labels.astype('U')
@@ -478,11 +552,11 @@ def get_channel_dtype(chan_info):
         dt = [('tick', 'i4'), ('marker', 'i4')]
     elif chan_info['kind'] in [6]:  # AdcMark data (waveform)
         dt = [('tick', 'i4'), ('marker', 'i4'),
-              #~ ('adc', 'S%d' % chan_info['n_extra'])]
+              # ('adc', 'S%d' % chan_info['n_extra'])]
               ('waveform', 'int16', chan_info['n_extra'] // 2)]
     elif chan_info['kind'] in [7]:  # RealMark data (waveform)
         dt = [('tick', 'i4'), ('marker', 'i4'),
-              #~ ('real', 'S%d' % chan_info['n_extra'])]
+              # ('real', 'S%d' % chan_info['n_extra'])]
               ('waveform', 'float32', chan_info['n_extra'] // 4)]
     elif chan_info['kind'] in [8]:  # TextMark data
         dt = [('tick', 'i4'), ('marker', 'i4'),


Test patch:
diff --git a/neo/rawio/tests/test_spike2rawio.py b/neo/rawio/tests/test_spike2rawio.py
index 320c3826..88f271ff 100644
--- a/neo/rawio/tests/test_spike2rawio.py
+++ b/neo/rawio/tests/test_spike2rawio.py
@@ -17,6 +17,7 @@ class TestSpike2RawIO(BaseTestRawIO, unittest.TestCase, ):
         'File_spike2_2.smr',
         'File_spike2_3.smr',
         '130322-1LY.smr',  # this is for bug 182
+        'multi_sampling.smr',  # this is for bug 466
     ]
     entities_to_test = files_to_download
 
diff --git a/neo/test/iotest/test_spike2io.py b/neo/test/iotest/test_spike2io.py
index 842116cb..8dd200a3 100644
--- a/neo/test/iotest/test_spike2io.py
+++ b/neo/test/iotest/test_spike2io.py
@@ -8,19 +8,52 @@ from __future__ import absolute_import, division
 
 import unittest
 
+import quantities as pq
+
 from neo.io import Spike2IO
 from neo.test.iotest.common_io_test import BaseTestIO
 
 
 class TestSpike2IO(BaseTestIO, unittest.TestCase, ):
     ioclass = Spike2IO
-    files_to_test = ['File_spike2_1.smr',
-                     'File_spike2_2.smr',
-                     'File_spike2_3.smr',
-                     '130322-1LY.smr',  # this is for bug 182
-                     ]
+    files_to_test = [
+        'File_spike2_1.smr',
+        'File_spike2_2.smr',
+        'File_spike2_3.smr',
+        '130322-1LY.smr',  # this is for bug 182
+        'multi_sampling.smr',  # this is for bug 466
+    ]
     files_to_download = files_to_test
 
 
+    def test_multi_sampling(self):
+        """
+        Some file can have several sampling_rate.
+        This one contain 3 differents signals sampling rate
+        """
+        filename = self.get_filename_path('multi_sampling.smr')
+        reader = Spike2IO(filename=filename)
+        bl = reader.read_block(signal_group_mode = 'group-by-same-units')
+        assert len(bl.segments) == 10
+        seg =bl.segments[0]
+        
+        # 7 group_id one per channel
+        assert len(seg.analogsignals) == 7
+        
+        # 1 channel for 1kHz
+        assert seg.analogsignals[0].shape == (14296, 1)
+        assert seg.analogsignals[0].sampling_rate == 1000*pq.Hz
+
+        # 4  channel for 2kHz
+        for c in range(1, 5):
+            assert seg.analogsignals[c].shape == (28632, 1)
+            assert seg.analogsignals[c].sampling_rate == 2000*pq.Hz
+
+        # 2 channel for 10kHz
+        for c in range(5, 7):
+            assert seg.analogsignals[c].shape == (114618, 1)
+            assert seg.analogsignals[c].sampling_rate == 10000*pq.Hz
+
+
 if __name__ == "__main__":
     unittest.main()