Browse Source

First running version with neo 0.8dev

Julia Sprenger 3 years ago
parent
commit
7441128360
1 changed files with 238 additions and 164 deletions
  1. 238 164
      code/reachgraspio/reachgraspio.py

+ 238 - 164
code/reachgraspio/reachgraspio.py

@@ -45,18 +45,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 import glob
 import os
 import re
+import warnings
 
 import numpy as np
 import odml.tools
 import quantities as pq
 
 import neo
-
-# Using old version of IO as long as available - should be deleted at some point
-try:
-    from neo.io import OldBlackrockIO as BlackrockIO
-except ImportError:
-    from neo.io.blackrockio import BlackrockIO
+from neo.io.blackrockio import BlackrockIO
 
 
 class ReachGraspIO(BlackrockIO):
@@ -93,11 +89,17 @@ class ReachGraspIO(BlackrockIO):
             File name of the .nev file (without extension). If None, the
             current spike-sorted version filename is used (see parameter
             filename above). Default: None.
-        sif_override (string):
+        nsx_to_load (int, list, 'max', 'all' (=None)) default None:
+            IDs of nsX file from which to load data, e.g., if set to
+            5 only data from the ns5 file are loaded.
+            If 'all', then all nsX will be loaded.
+            Contrary to previsous version of the IO  (<0.7), nsx_to_load
+            must be set at the init before parse_header().
+        sif_override (string): DEPRECATED
             File name of the .sif file (without extension). If None,
             filename is used.
             Default: None.
-        ccf_override (string):
+        ccf_override (string): DEPRECATED
             File name of the .ccf file (without extension). If None,
             filename is used.
             Default: None.
@@ -289,10 +291,9 @@ class ReachGraspIO(BlackrockIO):
         '65510': 'RW-ON (+CONF-HF)',
         '65513': 'RW-ON (+CONF-LF)',
         '65514': 'RW-ON (+CONF-SG)'}
-    event_labels_codes = dict(
-        [(k, []) for k in np.unique(list(event_labels_str.values()))]) #inefficient in Python2
+    event_labels_codes = dict([(k, []) for k in np.unique(list(event_labels_str.values()))])
     for k in list(event_labels_codes):
-        for l, v in event_labels_str.items(): #inefficient in Python2
+        for l, v in event_labels_str.items():
             if v == k:
                 event_labels_codes[k].append(l)
 
@@ -331,8 +332,7 @@ class ReachGraspIO(BlackrockIO):
         'SR': 5,
         'RW-ON': 6,
         'STOP': 7}
-    trial_const_sequence_str = dict(
-        (v, k) for k, v in trial_const_sequence_codes.items()) #inefficient in Python2
+    trial_const_sequence_str = dict((v, k) for k, v in trial_const_sequence_codes.items())
 
     # Create dictionaries for trial performances
     # (resulting decimal number from binary number created from trial_sequence)
@@ -345,10 +345,10 @@ class ReachGraspIO(BlackrockIO):
         'error<GO-ON': 175,
         'grip_error': 191,
         'correct_trial': 255}
-    performance_str = dict((v, k) for k, v in performance_codes.items())  #inefficient in Python2
+    performance_str = dict((v, k) for k, v in performance_codes.items())
 
     def __init__(
-            self, filename, odml_directory=None,
+            self, filename, odml_directory=None, nsx_to_load=None,
             nsx_override=None, nev_override=None,
             sif_override=None, ccf_override=None, odml_filename=None,
             verbose=False):
@@ -356,6 +356,13 @@ class ReachGraspIO(BlackrockIO):
         Constructor
         """
 
+        if sif_override is not None:
+            warnings.warn('`sif_override is deprecated.')
+
+        if ccf_override is not None:
+            warnings.warn('`ccf_override is deprecated.')
+
+
         # Remember choice whether to print diagnostic messages or not
         self._verbose = verbose
 
@@ -373,8 +380,7 @@ class ReachGraspIO(BlackrockIO):
         else:
             # find most recent spike sorting version
             nev_versions = [re.sub(
-                os.path.extsep + 'nev$', '', p) for p in glob.glob(
-                    filename + '*.nev')]
+                os.path.extsep + 'nev$', '', p) for p in glob.glob(filename + '*.nev')]
             nev_versions = [p.replace(filename, '') for p in nev_versions]
             if len(nev_versions):
                 sorting_postfix = sorted(nev_versions)[-1]
@@ -384,22 +390,24 @@ class ReachGraspIO(BlackrockIO):
 
         # Initialize file
         BlackrockIO.__init__(
-            self, filename, nsx_override=nsx_override,
-            nev_override=sorting_version, sif_override=sif_override,
-            ccf_override=ccf_override, verbose=verbose)
+            self, filename, nsx_to_load=nsx_to_load, nsx_override=nsx_override,
+            nev_override=sorting_version,  verbose=verbose)
 
         # if no odML directory is specified, use same directory as main files
         if not odml_directory:
-            odml_directory = os.path.dirname(self.filename)[:-1]
+            odml_directory = os.path.dirname(self.filename)
+            # remove potential trailing separators
+            if odml_directory[-1] == os.path.sep:
+                odml_directory = odml_directory[:-1]
 
         # remove extensions from odml override
         filen = os.path.split(self.filename)[-1]
         if odml_filename:
-            self._filenames['odml'] = ''.join(
-                [odml_directory, os.path.sep, odml_filename])
+            # strip potential extension
+            odmlname = os.path.splitext(odml_filename)[0]
+            self._filenames['odml'] = ''.join([odml_directory, os.path.sep, odmlname])
         else:
-            self._filenames['odml'] = ''.join(
-                [odml_directory, os.path.sep, filen])
+            self._filenames['odml'] = ''.join([odml_directory, os.path.sep, filen])
 
         file2check = ''.join([self._filenames['odml'], os.path.extsep, 'odml'])
         if os.path.exists(file2check):
@@ -427,6 +435,23 @@ class ReachGraspIO(BlackrockIO):
         else:
             self._load_spikesorting_info = False
 
+        # extract available neuronal ids
+        self.avail_electrode_ids = None
+        if self.odmldoc:
+            self.avail_electrode_ids = []
+            secs = self.odmldoc['UtahArray']['Array'].sections
+            for i in range(1, 101):
+                elidx = [s.properties['ID'].values for s in secs if
+                         s.name.startswith('Electrode') and
+                         s.properties['ConnectorAlignedID'].values[0] == i]
+                if len(elidx) == 0:
+                    self.avail_electrode_ids.append(-1)
+                elif len(elidx) == 1:
+                    self.avail_electrode_ids.append(elidx[0])
+                else:
+                    raise ValueError("Electrode IDs in odML file are corrupt. "
+                                     "ID %i occurs %i times" % (i, len(elidx)))
+
     def __is_set(self, flag, pos):
         """
         Checks if bit is set at the given position for flag. If flag is an
@@ -489,7 +514,7 @@ class ReachGraspIO(BlackrockIO):
         task_condition = 0
 
         if len(occurring_trtys) > 0:
-            for cnd, trtys in self.condition_str.items():  #inefficient in Python2
+            for cnd, trtys in self.condition_str.items():
                 if set(trtys) == set(occurring_trtys):
                     # replace with detected task condition
                     task_condition = cnd
@@ -511,23 +536,16 @@ class ReachGraspIO(BlackrockIO):
         tr_secs = sec.itersections(filter_func=ff)
         for trial_sec in tr_secs:
             for signalname in ['GripForceSignals', 'DisplacementSignal']:
-                for analog_events in trial_sec[
-                        'AnalogEvents'][signalname].properties:
+                for analog_events in trial_sec['AnalogEvents'][signalname].properties:
 
-                    time = analog_events.values * \
-                        pq.CompoundUnit(analog_events.unit)
+                    time = analog_events.values * pq.CompoundUnit(analog_events.unit)
                     if time >= t_start and time < t_stop:
                         event_name.append(analog_events.name)
                         event_time.append(time)
-                        trial_id.extend(
-                            trial_sec.properties['TrialID'].values)
-                        trial_timestamp_id.extend(
-                            trial_sec.properties[
-                                'TrialTimestampID'].values)
-                        performance_code.extend(
-                            trial_sec.properties['PerformanceCode'].values)
-                        trial_type.extend(
-                            trial_sec.properties['TrialType'].values)
+                        trial_id.extend(trial_sec.properties['TrialID'].values)
+                        trial_timestamp_id.extend(trial_sec.properties['TrialTimestampID'].values)
+                        performance_code.extend(trial_sec.properties['PerformanceCode'].values)
+                        trial_type.extend(trial_sec.properties['TrialType'].values)
 
         # Create event object with analog events
         analog_events = neo.Event(
@@ -564,13 +582,6 @@ class ReachGraspIO(BlackrockIO):
         events.name = "DigitalTrialEvents"
         events.description = "Trial " + events.description.lower()
 
-        # Uncomment for event and trial sequence debugging
-#        for ev in events.labels:
-#            if ev in list(self.event_labels_str):
-#                print ev, self.event_labels_str[ev]
-#            else:
-#                print ev
-
         # Extract beginning of first complete trial
         tson_label = self.event_labels_codes['TS-ON'][0]
         if tson_label in events.labels:
@@ -601,11 +612,8 @@ class ReachGraspIO(BlackrockIO):
                 if self.event_labels_str[l] == 'TS-ON':
                     if i > 0:
                         prev_ev = events.labels[i - 1]
-                        if self.event_labels_str[prev_ev] in \
-                                ['STOP', 'TS-OFF/STOP']:
-                            timestamp_id = int(events.times[i].rescale(
-                                self._BlackrockIO__nev_params(
-                                    'event_unit')).item())
+                        if self.event_labels_str[prev_ev] in ['STOP', 'TS-OFF/STOP']:
+                            timestamp_id = int(events.times[i].item())
                             trial_timestamp_ID.append(timestamp_id)
                             trial_event_labels.append('TS-ON')
                             trialsequence[timestamp_id] = self.__set_bit(
@@ -615,9 +623,7 @@ class ReachGraspIO(BlackrockIO):
                             trial_timestamp_ID.append(timestamp_id)
                             trial_event_labels.append('TS-ON-ERROR')
                     else:
-                        timestamp_id = int(events.times[i].rescale(
-                            self._BlackrockIO__nev_params(
-                                'event_unit')).item())
+                        timestamp_id = int(events.times[i].item())
                         trial_timestamp_ID.append(timestamp_id)
                         trial_event_labels.append('TS-ON')
                         trialsequence[timestamp_id] = self.__set_bit(
@@ -761,8 +767,7 @@ class ReachGraspIO(BlackrockIO):
         for tid in trial_timestamp_ID:
             if tid not in list(trialtypes):
                 trialtypes[tid] = 'NONE'
-        belongs_to_trialtype = [
-            trialtypes[tid] for tid in trial_timestamp_ID]
+        belongs_to_trialtype = [trialtypes[tid] for tid in trial_timestamp_ID]
         events.array_annotate(belongs_to_trialtype=belongs_to_trialtype)
 
         # add modified trial_performance_codes to annotations
@@ -828,33 +833,52 @@ class ReachGraspIO(BlackrockIO):
             for st in un.spiketrains:
                 st.annotate(**an_dict)
 
-    def __annotate_spiketrains_with_odml(self, sts):
-        """
-        Annotates spiketrains with metadata from odml file.
-        """
-
     def __annotate_analogsignals_with_odml(self, asig):
         """
         Annotates analogsignals with metadata from odml file.
         """
-        if self.odmldoc and asig.annotations['channel_id'] in range(1, 129):
-            # Annotate filter settings from odML
-            sec = self.odmldoc[
-                'Cerebus']['NeuralSignalProcessor']['NeuralSignals'][
-                'Filter_ns%i' % asig.annotations['nsx']]
-            asig.annotate(
-                filter_hi_pass_freq=pq.Quantity(
-                    sec.properties['HighPassFreq'].values[0],
-                    sec.properties['HighPassFreq'].unit),
-                filter_lo_pass_freq=pq.Quantity(
-                    sec.properties['LowPassFreq'].values[0],
-                    sec.properties['LowPassFreq'].unit),
-                filter_hi_pass_order=sec.properties[
-                    'HighPassOrder'].values[0],
-                filter_lo_pass_order=sec.properties[
-                    'LowPassOrder'].values[0],
-                filter_type=sec.properties[
-                    'Type'].values[0])
+
+        if self.odmldoc:
+            chids = asig.array_annotations['channel_ids']
+            neural_chids = [chid in self.avail_electrode_ids for chid in chids]
+
+            if not any(neural_chids):
+                asig.annotate(neural_signal=False)
+            elif all(neural_chids):
+                asig.annotate(neural_signal=True)
+
+                # Annotate filter settings from odML
+                nchan = asig.shape[-1]
+                sec = self.odmldoc['Cerebus']['NeuralSignalProcessor']['NeuralSignals'][
+                    'Filter_ns%i' % asig.array_annotations['nsx'][0]]
+                props = sec.properties
+                hi_pass_freq = np.full((nchan), pq.Quantity(props['HighPassFreq'].values[0],
+                                                            props['HighPassFreq'].unit))
+                lo_pass_freq = np.full((nchan), pq.Quantity(props['LowPassFreq'].values[0],
+                                                            props['LowPassFreq'].unit))
+                hi_pass_order = np.zeros_like(hi_pass_freq)
+                lo_pass_order = np.zeros_like(lo_pass_freq)
+                filter_type= np.empty((nchan), np.str)
+                for chidx in range(nchan):
+                    filter_name = 'Filter_ns%i' % asig.array_annotations['nsx'][chidx]
+                    sec = self.odmldoc['Cerebus']['NeuralSignalProcessor']['NeuralSignals'][filter_name]
+                    hi_pass_freq[chidx] = pq.Quantity(
+                        sec.properties['HighPassFreq'].values[0],
+                        sec.properties['HighPassFreq'].unit)
+                    lo_pass_freq[chidx] = pq.Quantity(
+                        sec.properties['LowPassFreq'].values[0],
+                        sec.properties['LowPassFreq'].unit)
+                    hi_pass_order[chidx] = sec.properties['HighPassOrder'].values[0]
+                    lo_pass_order[chidx] = sec.properties['LowPassOrder'].values[0]
+                    filter_type[chidx] = sec.properties['Type'].values[0]
+
+                asig.array_annotations.update(dict(
+                    hi_pass_freq=hi_pass_freq,
+                    lo_pass_freq=lo_pass_freq,
+                    hi_pass_order=hi_pass_order,
+                    lo_pass_order=lo_pass_order,
+                    filter_type=filter_type
+                ))
 
     def __annotate_channelindex_with_odml(self, chidx):
         """
@@ -899,8 +923,7 @@ class ReachGraspIO(BlackrockIO):
                             st.annotate(**rej_dict)
 
             # Annotate connector aligned ID to channel
-            if chidx.channel_ids[0] in \
-                    chidx.block.annotations['avail_electrode_ids']:
+            if chidx.channel_ids[0] in chidx.block.annotations['avail_electrode_ids']:
                 ca_dict = {
                     'connector_aligned_id': chidx.block.annotations[
                         'avail_electrode_ids'].index(chidx.channel_ids[0])+1}
@@ -928,8 +951,7 @@ class ReachGraspIO(BlackrockIO):
             project_subtype=sec.properties['Subtype'].values)
 
         sec = self.odmldoc['Project']['TaskDesigns']
-        bl.annotate(
-            taskdesigns=[v for v in sec.properties['UsedDesign'].values])
+        bl.annotate( taskdesigns=[v for v in sec.properties['UsedDesign'].values])
 
         sec = self.odmldoc['Subject']
         bl.annotate(
@@ -960,29 +982,21 @@ class ReachGraspIO(BlackrockIO):
             arraygrid_col_num=sec.properties['GridColumns'].values)
 
         secs = self.odmldoc['UtahArray']['Array'].sections
-        bl.annotate(
-            avail_electrode_ids=[])
-        for i in range(1, 101):
-            elidx = [s.properties['ID'].values for s in secs if
-                     s.name.startswith('Electrode') and
-                     s.properties['ConnectorAlignedID'].values[0] == i]
-            if len(elidx) == 0:
-                bl.annotations['avail_electrode_ids'].append(-1)
-            elif len(elidx) == 1:
-                bl.annotations['avail_electrode_ids'].append(elidx[0])
-            else:
-                raise ValueError("Electrode IDs in odML file are corrupt. "
-                                 "ID %i occurs %i times" % (i, len(elidx)))
+        bl.annotate(avail_electrode_ids=self.avail_electrode_ids)
 
         # TODO: add list of behavioral channels
         # bl.annotate(avail_behavsig_indexes=[])
 
     def __correct_filter_shifts(self, asig):
-        if self.odmldoc and asig.annotations['channel_id'] in range(1, 129):
+        if self.odmldoc and asig.annotations['neural_signal']:
+            # assert all signals are originating from same nsx file
+            if len(np.unique(asig.array_annotations['nsx'])) > 1:
+                raise ValueError('Multiple nsx file origins (%s) in single AnalogSignal'
+                                 ''.format(asig.array_annotations['nsx']))
+            
             # Get and correct for shifts
-            sec = self.odmldoc[
-                'Cerebus']['NeuralSignalProcessor']['NeuralSignals'][
-                'Filter_ns%i' % asig.annotations['nsx']]
+            filter_name = 'Filter_ns%i' % asig.array_annotations['nsx'][0] # use nsx of 1st signal
+            sec = self.odmldoc['Cerebus']['NeuralSignalProcessor']['NeuralSignals'][filter_name]
             shift = pq.Quantity(
                 sec.properties['EstimatedShift'].values[0],
                 sec.properties['EstimatedShift'].unit)
@@ -1050,10 +1064,10 @@ class ReachGraspIO(BlackrockIO):
         return merged_event
 
     def read_block(
-            self, index=None, name=None, description=None, nsx_to_load='none',
+            self, index=None, block_index=0, name=None, description=None, nsx_to_load='none',
             n_starts=None, n_stops=None, channels=range(1, 97), units='none',
             load_waveforms=False, load_events=False, scaling='raw',
-            correct_filter_shifts=True, lazy=False, cascade=True):
+            correct_filter_shifts=True, lazy=False, cascade=True, **kwargs):
         """
         Reads file contents as a Neo Block.
 
@@ -1064,33 +1078,35 @@ class ReachGraspIO(BlackrockIO):
         The Block contains one ChannelIndex per channel.
 
         Args:
-            index (None, int):
+            index (None, int): DEPRECATED
                 If not None, index of block is set to user input.
+            block_index (int):
+                Index of block to load.
             name (None, str):
                 If None, name is set to default, otherwise it is set to user
                 input.
             description (None, str):
                 If None, description is set to default, otherwise it is set to
                 user input.
-            nsx_to_load (int, list, str):
+            nsx_to_load (int, list, str): DEPRECATED
                 ID(s) of nsx file(s) from which to load data, e.g., if set to
                 5 only data from the ns5 file are loaded. If 'none' or empty
                 list, no nsx files and therefore no analog signals are loaded.
                 If 'all', data from all available nsx are loaded.
-            n_starts (None, Quantity, list):
+            n_starts (None, Quantity, list): DEPRECATED
                 Start times for data in each segment. Number of entries must be
                 equal to length of n_stops. If None, intrinsic recording start
                 times of files set are used.
-            n_stops (None, Quantity, list):
+            n_stops (None, Quantity, list): DEPRECATED
                 Stop times for data in each segment. Number of entries must be
                 equal to length of n_starts. If None, intrinsic recording stop
                 times of files set are used.
-            channels (int, list, str):
+            channels (int, list, str): DEPRECATED
                 Channel id(s) from which to load data. If 'none' or empty list,
                 no channels and therefore no analog signal or spiketrains are
                 loaded. If 'all', all available channels are loaded. By
                 default, all neural channels (1-96) are loaded.
-            units (int, list, str, dict):
+            units (int, list, str, dict): DEPRECATED
                 ID(s) of unit(s) to load. If 'none' or empty list, no units and
                 therefore no spiketrains are loaded. If 'all', all available
                 units are loaded. If dict, the above can be specified
@@ -1098,9 +1114,9 @@ class ReachGraspIO(BlackrockIO):
                 loads unit 5 from channel 1 and all units from channel 2.
             load_waveforms (boolean):
                 If True, waveforms are attached to all loaded spiketrains.
-            load_events (boolean):
+            load_events (boolean): DEPRECATED
                 If True, all recorded events are loaded.
-            scaling (str):
+            scaling (str): DEPRECATED
                 Determines whether time series of individual
                 electrodes/channels are returned as AnalogSignals containing
                 raw integer samples ('raw'), or scaled to arrays of floats
@@ -1115,8 +1131,10 @@ class ReachGraspIO(BlackrockIO):
                 /Cerebus/NeuralSignalProcessor/NeuralSignals/Filter_nsX/
             lazy (bool):
                 If True, only the shape of the data is loaded.
-            cascade (bool or "lazy"):
+            cascade (bool or "lazy"): DEPRECATED
                 If True, only the block without children is returned.
+            kwargs:
+                Additional keyword arguments are forwarded to the BlackrockIO.
 
         Returns:
             Block (neo.segment.Block):
@@ -1434,23 +1452,48 @@ class ReachGraspIO(BlackrockIO):
         if not name:
             name = 'Reachgrasp Recording Data Block'
         if not description:
-            description = \
-                "Block of reach-to-grasp project data from Blackrock file set."
+            description = "Block of reach-to-grasp project data from Blackrock file set."
+
+        if index is not None:
+            warnings.warn('`index` is deprecated and will be replaced by `block_index`.')
+
+        if nsx_to_load != 'none':
+            warnings.warn('`nsx_to_load` is deprecated for `read_block`. '
+                          'Specify `nsx_to_load when initializing the IO or use lazy loading.')
+        if n_starts is not None:
+            warnings.warn('`n_starts` is deprecated. Use lazy loading instead.')
+
+        if n_stops is not None:
+            warnings.warn('`n_stops` is deprecated. Use lazy loading instead.')
+
+        if channels != range(1, 97):
+            warnings.warn('`channels` is deprecated. Use lazy loading instead.')
+
+        if units != 'none':
+            warnings.warn('`units` is deprecated. Use lazy loading instead.')
+
+        if load_events is not False:
+            warnings.warn('`load_events` is deprecated. Use lazy loading instead.')
+
+        if scaling != 'raw':
+            warnings.warn('`scaling` is deprecated.')
+
+        if cascade is not True:
+            warnings.warn('`cascade` is deprecated. Use lazy loading instead.')
 
         # Load neo block
         bl = BlackrockIO.read_block(
-            self, index=index, name=name, description=description,
-            nsx_to_load=nsx_to_load, n_starts=n_starts, n_stops=n_stops,
-            channels=channels, units=units, load_waveforms=load_waveforms,
-            load_events=load_events, scaling=scaling, lazy=lazy,
-            cascade=cascade)
+            self, block_index=block_index, load_waveforms=load_waveforms, lazy=lazy, **kwargs)
+
+        if name is not None:
+            bl.name = name
+        if description is not None:
+            bl.description = description
 
         bl.annotate(conditions=[])
         for seg in bl.segments:
-            if load_events and not lazy:
-                if 'condition' in list(seg.annotations):
-                    bl.annotations['conditions'].append(
-                        seg.annotations['condition'])
+            if 'condition' in list(seg.annotations):
+                bl.annotations['conditions'].append(seg.annotations['condition'])
 
         if self.odmldoc:
             self.__annotate_block_with_odml(bl)
@@ -1465,10 +1508,10 @@ class ReachGraspIO(BlackrockIO):
         return bl
 
     def read_segment(
-            self, n_start, n_stop, name=None, description=None, index=None,
+            self, block_index=0, seg_index=0, name=None, description=None, index=None,
             nsx_to_load='none', channels=range(1, 97), units='none',
             load_waveforms=False, load_events=False, scaling='raw',
-            correct_filter_shifts=True, lazy=False, cascade=True):
+            correct_filter_shifts=True, lazy=False, cascade=True, **kwargs):
         """
         Reads file contents as a Neo Block.
 
@@ -1479,31 +1522,32 @@ class ReachGraspIO(BlackrockIO):
         The Block contains one ChannelIndex per channel.
 
         Args:
-            n_start (Quantity):
+            n_start (Quantity): DEPRECATED
                 Start time of maximum time range of signals contained in this
-                segment.
-            n_stop (Quantity):
+                segment. Deprecated, use lazy loading instead.
+            n_stop (Quantity): DEPRECATED
                 Stop time of maximum time range of signals contained in this
-                segment.
+                segment. Deprecated, use lazy loading instead.
             name (None, string):
                 If None, name is set to default, otherwise it is set to user
                 input.
             description (None, string):
                 If None, description is set to default, otherwise it is set to
                 user input.
-            index (None, int):
+            index (None, int): DEPRECATED
                 If not None, index of segment is set to user index.
+                Deprecated, use `seg_index` instead.
             nsx_to_load (int, list, str):
                 ID(s) of nsx file(s) from which to load data, e.g., if set to
                 5 only data from the ns5 file are loaded. If 'none' or empty
                 list, no nsx files and therefore no analog signals are loaded.
                 If 'all', data from all available nsx are loaded.
-            channels (int, list, str):
+            channels (int, list, str): DEPRECATED
                 Channel id(s) from which to load data. If 'none' or empty list,
                 no channels and therefore no analog signal or spiketrains are
                 loaded. If 'all', all available channels are loaded.  By
                 default, all neural channels (1-96) are loaded.
-            units (int, list, str, dict):
+            units (int, list, str, dict): DEPRECATED
                 ID(s) of unit(s) to load. If 'none' or empty list, no units and
                 therefore no spiketrains are loaded. If 'all', all available
                 units are loaded. If dict, the above can be specified
@@ -1511,9 +1555,9 @@ class ReachGraspIO(BlackrockIO):
                 loads unit 5 from channel 1 and all units from channel 2.
             load_waveforms (boolean):
                 If True, waveforms are attached to all loaded spiketrains.
-            load_events (boolean):
+            load_events (boolean): DEPRECATED
                 If True, all recorded events are loaded.
-            scaling (str):
+            scaling (str): DEPRECATED
                 Determines whether time series of individual
                 electrodes/channels are returned as AnalogSignals containing
                 raw integer samples ('raw'), or scaled to arrays of floats
@@ -1528,52 +1572,82 @@ class ReachGraspIO(BlackrockIO):
                 /Cerebus/NeuralSignalProcessor/NeuralSignals/Filter_nsX/
             lazy (boolean):
                 If True, only the shape of the data is loaded.
-            cascade (boolean):
+            cascade (boolean): DEPRECATED
                 If True, only the segment without children is returned.
+            kwargs:
+                Additional keyword arguments are forwarded to the BlackrockIO.
 
         Returns:
             Segment (neo.segment.Segment):
                 Segment linking to all loaded Neo objects. See documentation of
                 read_block() for a full list of annotations per Neo object.
         """
+
+        if index is not None:
+            warnings.warn('`index` is deprecated and will be replaced by `segment_index`.')
+
+        if nsx_to_load != 'none':
+            warnings.warn('`nsx_to_load` is deprecated for `read_block`. '
+                          'Specify `nsx_to_load when initializing the IO or use lazy loading.')
+
+        if channels != range(1, 97):
+            warnings.warn('`channels` is deprecated. Use lazy loading instead.')
+
+        if units != 'none':
+            warnings.warn('`units` is deprecated. Use lazy loading instead.')
+
+        if load_events is not False:
+            warnings.warn('`load_events` is deprecated. Use lazy loading instead.')
+
+        if scaling != 'raw':
+            warnings.warn('`scaling` is deprecated.')
+
+        if cascade is not True:
+            warnings.warn('`cascade` is deprecated. Use lazy loading instead.')
+
         # Load neo block
         seg = BlackrockIO.read_segment(
-            self, n_start, n_stop, name=name, description=description,
-            index=index, nsx_to_load=nsx_to_load, channels=channels,
-            units=units, load_waveforms=load_waveforms,
-            load_events=load_events, scaling=scaling, lazy=lazy,
-            cascade=cascade)
+            self, block_index=block_index, seg_index=seg_index, load_waveforms=load_waveforms,
+            lazy=lazy, **kwargs)
+
+        if name is not None:
+            seg.name = name
+        if description is not None:
+            seg.description = description
+            
+        # load data of all events and epochs
+        for ev_idx, event in enumerate(seg.events):
+            seg.events[ev_idx] = event.load()
+            seg.events[ev_idx].segment = seg
+        for ep_idx, epoch in enumerate(seg.epochs):
+            seg.epochs[ep_idx] = epoch.load()
+            seg.epochs[ep_idx].segment = seg
 
         for asig in seg.analogsignals:
-            asig.name = str(asig.name)
             self.__annotate_analogsignals_with_odml(asig)
             if correct_filter_shifts:
                 self.__correct_filter_shifts(asig)
 
-        if load_events and not lazy:
-            for ev in seg.events:
-                # Modify digital trial events to include semantic event
-                # informations
-                if ev.name == 'digital_input_port':
-                    self.__annotate_dig_trial_events(ev)
-                    self.__add_rejection_to_event(ev)
-
-                    cnd = self.__extract_task_condition(
-                        ev.array_annotations['belongs_to_trialtype'])
-                    seg.annotate(condition=cnd)
-
-            # If digital trial events exist, extract analog events from odML
-            # and create one common event array
-            if len(seg.events) > 0 and self.odmldoc:
-                analog_event = self.__extract_analog_events_from_odml(
-                    seg.t_start, seg.t_stop)
-                self.__add_rejection_to_event(analog_event)
-                seg.events.append(analog_event)
-
-                merged_event = self.__merge_digital_analog_events(
-                    seg.events)
-                self.__add_rejection_to_event(merged_event)
-                seg.events.append(merged_event)
+        for ev in seg.events:
+            # Modify digital trial events to include semantic event
+            # informations
+            if ev.name == 'digital_input_port':
+                self.__annotate_dig_trial_events(ev)
+                self.__add_rejection_to_event(ev)
+
+                cnd = self.__extract_task_condition(ev.array_annotations['belongs_to_trialtype'])
+                seg.annotate(condition=cnd)
+
+        # If digital trial events exist, extract analog events from odML
+        # and create one common event array
+        if len(seg.events) > 0 and self.odmldoc:
+            analog_event = self.__extract_analog_events_from_odml(seg.t_start, seg.t_stop)
+            self.__add_rejection_to_event(analog_event)
+            seg.events.append(analog_event)
+
+            merged_event = self.__merge_digital_analog_events(seg.events)
+            self.__add_rejection_to_event(merged_event)
+            seg.events.append(merged_event)
 
         return seg