def _initialize_subrecording_extractor(self, recording):
     if isinstance(self._bad_channel_ids, (list, np.ndarray)):
         active_channels = []
         for chan in recording.get_channel_ids():
             if chan not in self._bad_channel_ids:
                 active_channels.append(chan)
         self._subrecording = SubRecordingExtractor(
             recording, channel_ids=active_channels)
     elif self._bad_channel_ids is None:
         start_frame = recording.get_num_frames() // 2
         end_frame = int(start_frame +
                         self._seconds * recording.get_sampling_frequency())
         if end_frame > recording.get_num_frames():
             end_frame = recording.get_num_frames()
         traces = recording.get_traces(start_frame=start_frame,
                                       end_frame=end_frame)
         stds = np.std(traces, axis=1)
         bad_channel_ids = [
             ch for ch, std in enumerate(stds)
             if std > self._bad_threshold * np.median(stds)
         ]
         if self.verbose:
             print('Automatically removing channels:', bad_channel_ids)
         active_channels = []
         for chan in recording.get_channel_ids():
             if chan not in bad_channel_ids:
                 active_channels.append(chan)
         self._subrecording = SubRecordingExtractor(
             recording, channel_ids=active_channels)
     else:
         self._subrecording = recording
     self.active_channels = self._subrecording.get_channel_ids()
Esempio n. 2
0
class RemoveBadChannelsRecording(BasePreprocessorRecordingExtractor):
    preprocessor_name = 'RemoveBadChannels'

    def __init__(self, recording, bad_channel_ids, bad_threshold, seconds,
                 verbose):
        self._bad_channel_ids = bad_channel_ids
        self._bad_threshold = bad_threshold
        self._seconds = seconds
        self.verbose = verbose
        self._initialize_subrecording_extractor(recording)
        BasePreprocessorRecordingExtractor.__init__(self, self._subrecording)
        self._kwargs = {
            'recording': recording.make_serialized_dict(),
            'bad_channel_ids': bad_channel_ids,
            'bad_threshold': bad_threshold,
            'seconds': seconds,
            'verbose': verbose
        }

    @check_get_traces_args
    def get_traces(self, channel_ids=None, start_frame=None, end_frame=None):
        traces = self._subrecording.get_traces(channel_ids=channel_ids,
                                               start_frame=start_frame,
                                               end_frame=end_frame)
        return traces

    def _initialize_subrecording_extractor(self, recording):
        if isinstance(self._bad_channel_ids, (list, np.ndarray)):
            active_channels = []
            for chan in recording.get_channel_ids():
                if chan not in self._bad_channel_ids:
                    active_channels.append(chan)
            self._subrecording = SubRecordingExtractor(
                recording, channel_ids=active_channels)
        elif self._bad_channel_ids is None:
            start_frame = recording.get_num_frames() // 2
            end_frame = int(start_frame +
                            self._seconds * recording.get_sampling_frequency())
            if end_frame > recording.get_num_frames():
                end_frame = recording.get_num_frames()
            traces = recording.get_traces(start_frame=start_frame,
                                          end_frame=end_frame)
            stds = np.std(traces, axis=1)
            bad_channel_ids = [
                ch for ch, std in enumerate(stds)
                if std > self._bad_threshold * np.median(stds)
            ]
            if self.verbose:
                print('Automatically removing channels:', bad_channel_ids)
            active_channels = []
            for chan in recording.get_channel_ids():
                if chan not in bad_channel_ids:
                    active_channels.append(chan)
            self._subrecording = SubRecordingExtractor(
                recording, channel_ids=active_channels)
        else:
            self._subrecording = recording
        self.active_channels = self._subrecording.get_channel_ids()
Esempio n. 3
0
def get_sub_extractors_by_property(extractor, property_name, return_property_list=False):
    '''Returns a list of SubRecordingExtractors from this RecordingExtractor based on the given
    property_name (e.g. group)

    Parameters
    ----------
    property_name: str
        The property used to subdivide the extractor
    return_property_list: bool
        If True the property list is returned

    Returns
    -------
    sub_list: list
        The list of subextractors to be returned.
    OR
    sub_list, prop_list
        If return_property_list is True, the property list will be returned as well.
    '''
    from spikeextractors import RecordingExtractor, SortingExtractor, SubRecordingExtractor, SubSortingExtractor

    if isinstance(extractor, RecordingExtractor):
        if property_name not in extractor.get_shared_channel_property_names():
            raise ValueError("'property_name' must be must be a property of the recording channels")
        else:
            sub_list = []
            recording = extractor
            properties = np.array([recording.get_channel_property(chan, property_name)
                                   for chan in recording.get_channel_ids()])
            prop_list = np.unique(properties)
            for prop in prop_list:
                prop_idx = np.where(prop == properties)
                chan_idx = list(np.array(recording.get_channel_ids())[prop_idx])
                sub_list.append(SubRecordingExtractor(recording, channel_ids=chan_idx))
            if return_property_list:
                return sub_list, prop_list
            else:
                return sub_list
    elif isinstance(extractor, SortingExtractor):
        if property_name not in extractor.get_shared_unit_property_names():
            raise ValueError("'property_name' must be must be a property of the units")
        else:
            sub_list = []
            sorting = extractor
            properties = np.array([sorting.get_unit_property(unit, property_name)
                                   for unit in sorting.get_unit_ids()])
            prop_list = np.unique(properties)
            for prop in prop_list:
                prop_idx = np.where(prop == properties)
                unit_idx = list(np.array(sorting.get_unit_ids())[prop_idx])
                sub_list.append(SubSortingExtractor(sorting, unit_ids=unit_idx))
            if return_property_list:
                return sub_list, prop_list
            else:
                return sub_list
    else:
        raise ValueError("'extractor' must be a RecordingExtractor or a SortingExtractor")
Esempio n. 4
0
def getSubExtractorsByProperty(extractor, property_name):
    '''Divides Recording or Sorting Extractor based on the property_name (e.g. group)

    Parameters
    ----------
    extractor: RecordingExtractor or SortingExtractor
        The extractor to be subdivided in subextractors
    property_name: str
        The property used to subdivide the extractor

    Returns
    -------
    List of subextractors

    '''
    if isinstance(extractor, RecordingExtractor):
        if property_name not in extractor.get_channel_property_names():
            raise ValueError(
                "'property_name' must be must be a property of the recording channels"
            )
        else:
            sub_list = []
            recording = extractor
            properties = np.array([
                recording.get_channel_property(chan, property_name)
                for chan in recording.get_channel_ids()
            ])
            prop_list = np.unique(properties)
            for prop in prop_list:
                prop_idx = np.where(prop == properties)
                chan_idx = list(
                    np.array(recording.get_channel_ids())[prop_idx])
                sub_list.append(
                    SubRecordingExtractor(recording, channel_ids=chan_idx))
            return sub_list
    elif isinstance(extractor, SortingExtractor):
        if property_name not in extractor.get_unit_propertyNames():
            raise ValueError(
                "'property_name' must be must be a property of the units")
        else:
            sub_list = []
            sorting = extractor
            properties = np.array([
                sorting.get_unit_property(unit, property_name)
                for unit in sorting.get_unit_ids()
            ])
            prop_list = np.unique(properties)
            for prop in prop_list:
                prop_idx = np.where(prop == properties)
                unit_idx = list(np.array(sorting.get_unit_ids())[prop_idx])
                sub_list.append(SubSortingExtractor(sorting,
                                                    unit_ids=unit_idx))
            return sub_list
    else:
        raise ValueError(
            "'extractor' must be a RecordingExtractor or a SortingExtractor")
Esempio n. 5
0
def clip_recording(
        trial_numbers: Iterable,
        trial_times: Iterable,
        recording: RecordingExtractor = None) -> SubRecordingExtractor:
    """
    Clip the recording to align with the trials information.

    It was found in the test data that sometimes the nidq and recording start at unreset trial values; this clips that
    end of the recording and returns all data and times starting from the new point (trial number zero).

    Parameters
    ----------
    recording : RecordingExtractor
        If passed, will return a SubRecordingExtractor clipped to align with the trials info.
    """
    return SubRecordingExtractor(
        parent_recording=recording,
        start_frame=recording.time_to_frame(
            times=trial_times[list(trial_numbers).index(0)][0]))
Esempio n. 6
0
def load_probe_file(recording, probe_file, channel_map=None, channel_groups=None, verbose=False):
    '''This function returns a SubRecordingExtractor that contains information from the given
    probe file (channel locations, groups, etc.) If a .prb file is given, then 'location' and 'group' 
    information for each channel is added to the SubRecordingExtractor. If a .csv file is given, then 
    it will only add 'location' to the SubRecordingExtractor.

    Parameters
    ----------
    recording: RecordingExtractor
        The recording extractor to channel information
    probe_file: str
        Path to probe file. Either .prb or .csv
    verbose: bool
        If True, output is verbose

    Returns
    ---------
    subrecording = SubRecordingExtractor
        The extractor containing all of the probe information.
    '''
    from .subrecordingextractor import SubRecordingExtractor
    probe_file = Path(probe_file)
    if probe_file.suffix == '.prb':
        probe_dict = read_python(probe_file)
        if 'channel_groups' in probe_dict.keys():
            ordered_channels = np.array([], dtype=int)
            groups = sorted(probe_dict['channel_groups'].keys())
            for cgroup_id in groups:
                cgroup = probe_dict['channel_groups'][cgroup_id]
                for key_prop, prop_val in cgroup.items():
                    if key_prop == 'channels':
                        ordered_channels = np.concatenate((ordered_channels, prop_val))
            if not np.all([chan in recording.get_channel_ids() for chan in ordered_channels]) and verbose:
                print('Some channel in PRB file are not in original recording')
            present_ordered_channels = [chan for chan in ordered_channels if chan in recording.get_channel_ids()]
            subrecording = SubRecordingExtractor(recording, channel_ids=present_ordered_channels)
            for cgroup_id in groups:
                cgroup = probe_dict['channel_groups'][cgroup_id]
                if 'channels' not in cgroup.keys() and len(groups) > 1:
                    raise Exception("If more than one 'channel_group' is in the probe file, the 'channels' field"
                                    "for each channel group is required")
                elif 'channels' not in cgroup.keys():
                    channels_in_group = subrecording.get_num_channels()
                    channels_id_in_group = subrecording.get_channel_ids()
                else:
                    channels_in_group = len(cgroup['channels'])
                    channels_id_in_group = cgroup['channels']
                for key_prop, prop_val in cgroup.items():
                    if key_prop == 'channels':
                        for i_ch, prop in enumerate(prop_val):
                            if prop in subrecording.get_channel_ids():
                                subrecording.set_channel_property(prop, 'group', int(cgroup_id))
                    elif key_prop == 'geometry' or key_prop == 'location':
                        if isinstance(prop_val, dict):
                            if len(prop_val.keys()) != channels_in_group and verbose:
                                print('geometry in PRB does not have the same length as channel in group')
                            for (i_ch, prop) in prop_val.items():
                                if i_ch in subrecording.get_channel_ids():
                                    subrecording.set_channel_property(i_ch, 'location', prop)
                        elif isinstance(prop_val, (list, np.ndarray)) and len(prop_val) == channels_in_group:
                            if 'channels' not in cgroup.keys():
                                raise Exception("'geometry'/'location' in the .prb file can be a list only if "
                                                "'channels' field is specified.")
                            if len(prop_val) != channels_in_group and verbose:
                                print('geometry in PRB does not have the same length as channel in group')
                            for (i_ch, prop) in zip(channels_id_in_group, prop_val):
                                if i_ch in subrecording.get_channel_ids():
                                    subrecording.set_channel_property(i_ch, 'location', prop)
                    else:
                        if isinstance(prop_val, dict) and len(prop_val.keys()) == channels_in_group:
                            for (i_ch, prop) in prop_val.items():
                                if i_ch in subrecording.get_channel_ids():
                                    subrecording.set_channel_property(i_ch, key_prop, prop)
                        elif isinstance(prop_val, (list, np.ndarray)) and len(prop_val) == channels_in_group:
                            for (i_ch, prop) in zip(channels_id_in_group, prop_val):
                                if i_ch in subrecording.get_channel_ids():
                                    subrecording.set_channel_property(i_ch, key_prop, prop)
                # create dummy locations
                if 'geometry' not in cgroup.keys() and 'location' not in cgroup.keys():
                    for i, chan in enumerate(subrecording.get_channel_ids()):
                        subrecording.set_channel_property(chan, 'location', [0, i])
        else:
            raise AttributeError("'.prb' file should contain the 'channel_groups' field")

    elif probe_file.suffix == '.csv':
        if channel_map is not None:
            assert np.all([chan in channel_map for chan in recording.get_channel_ids()]), \
                "all channel_ids in 'channel_map' must be in the original recording channel ids"
            subrecording = SubRecordingExtractor(recording, channel_ids=channel_map)
        else:
            subrecording = SubRecordingExtractor(recording, channel_ids=recording.get_channel_ids())
        with probe_file.open() as csvfile:
            posreader = csv.reader(csvfile)
            row_count = 0
            loaded_pos = []
            for pos in (posreader):
                row_count += 1
                loaded_pos.append(pos)
            assert len(subrecording.get_channel_ids()) == row_count, "The .csv file must contain as many " \
                                                                     "rows as the number of channels in the recordings"
            for i_ch, pos in zip(subrecording.get_channel_ids(), loaded_pos):
                if i_ch in subrecording.get_channel_ids():
                    subrecording.set_channel_property(i_ch, 'location', list(np.array(pos).astype(float)))
            if channel_groups is not None and len(channel_groups) == len(subrecording.get_channel_ids()):
                for i_ch, chg in zip(subrecording.get_channel_ids(), channel_groups):
                    if i_ch in subrecording.get_channel_ids():
                        subrecording.set_channel_property(i_ch, 'group', chg)
    else:
        raise NotImplementedError("Only .csv and .prb probe files can be loaded.")

    subrecording._kwargs['probe_file'] = str(probe_file.absolute())
    return subrecording
Esempio n. 7
0
def loadProbeFile(recording,
                  probe_file,
                  channel_map=None,
                  channel_groups=None):
    '''Loads channel information into recording extractor. If a .prb file is given,
    then 'location' and 'group' information for each channel is stored. If a .csv
    file is given, then it will only store 'location'

    Parameters
    ----------
    recording: RecordingExtractor
        The recording extractor to channel information
    probe_file: str
        Path to probe file. Either .prb or .csv
    Returns
    ---------
    subRecordingExtractor
    '''
    probe_file = Path(probe_file)
    if probe_file.suffix == '.prb':
        probe_dict = read_python(probe_file)
        if 'channel_groups' in probe_dict.keys():
            ordered_channels = np.array([], dtype=int)
            groups = sorted(probe_dict['channel_groups'].keys())
            for cgroup_id in groups:
                cgroup = probe_dict['channel_groups'][cgroup_id]
                for key_prop, prop_val in cgroup.items():
                    if key_prop == 'channels':
                        ordered_channels = np.concatenate(
                            (ordered_channels, prop_val))

            if list(ordered_channels) == recording.get_channel_ids():
                subrecording = recording
            else:
                assert np.all([chan in recording.get_channel_ids() for chan in ordered_channels]), \
                    "all channel_ids in the 'channels' section of the probe file " \
                    "must be in the original recording channel ids"
                subrecording = SubRecordingExtractor(
                    recording, channel_ids=list(ordered_channels))
            for cgroup_id in groups:
                cgroup = probe_dict['channel_groups'][cgroup_id]
                if 'channels' not in cgroup.keys() and len(groups) > 1:
                    raise Exception(
                        "If more than one 'channel_group' is in the probe file, the 'channels' field"
                        "for each channel group is required")
                elif 'channels' not in cgroup.keys():
                    channels_in_group = subrecording.get_num_channels()
                else:
                    channels_in_group = len(cgroup['channels'])
                for key_prop, prop_val in cgroup.items():
                    if key_prop == 'channels':
                        for i_ch, prop in enumerate(prop_val):
                            subrecording.set_channel_property(
                                prop, 'group', int(cgroup_id))
                    elif key_prop == 'geometry' or key_prop == 'location':
                        if isinstance(prop_val, dict) and len(
                                prop_val.keys()) == channels_in_group:
                            for (i_ch, prop) in prop_val.items():
                                subrecording.set_channel_property(
                                    i_ch, 'location', prop)
                        elif isinstance(prop_val, (list, np.ndarray)) and len(
                                prop_val) == channels_in_group:
                            for (i_ch,
                                 prop) in zip(subrecording.get_channel_ids(),
                                              prop_val):
                                subrecording.set_channel_property(
                                    i_ch, 'location', prop)
                    else:
                        if isinstance(prop_val, dict) and len(
                                prop_val.keys()) == channels_in_group:
                            for (i_ch, prop) in prop_val.items():
                                subrecording.set_channel_property(
                                    i_ch, key_prop, prop)
                        elif isinstance(prop_val, (list, np.ndarray)) and len(
                                prop_val) == channels_in_group:
                            for (i_ch,
                                 prop) in zip(subrecording.get_channel_ids(),
                                              prop_val):
                                subrecording.set_channel_property(
                                    i_ch, key_prop, prop)
                # create dummy locations
                if 'geometry' not in cgroup.keys(
                ) and 'location' not in cgroup.keys():
                    for i, chan in enumerate(subrecording.get_channel_ids()):
                        subrecording.set_channel_property(
                            chan, 'location', [i, 0])
        else:
            raise AttributeError(
                "'.prb' file should contain the 'channel_groups' field")

    elif probe_file.suffix == '.csv':
        if channel_map is not None:
            assert np.all([chan in recording.get_channel_ids() for chan in channel_map]), \
                "all channel_ids in 'channel_map' must be in the original recording channel ids"
            subrecording = SubRecordingExtractor(recording,
                                                 channel_ids=channel_map)
        else:
            subrecording = recording
        with open(probe_file) as csvfile:
            posreader = csv.reader(csvfile)
            row_count = 0
            loaded_pos = []
            for pos in (posreader):
                row_count += 1
                loaded_pos.append(pos)
            assert len(
                subrecording.get_channel_ids()
            ) == row_count, "The .csv file must contain as many rows as the number of channels in the recordings"
            for i_ch, pos in zip(subrecording.get_channel_ids(), loaded_pos):
                subrecording.set_channel_property(
                    i_ch, 'location', list(np.array(pos).astype(float)))
            if channel_groups is not None and len(channel_groups) == len(
                    subrecording.get_channel_ids()):
                for i_ch, chg in zip(subrecording.get_channel_ids(),
                                     channel_groups):
                    subrecording.set_channel_property(i_ch, 'group', chg)
    else:
        raise NotImplementedError(
            "Only .csv and .prb probe files can be loaded.")

    return subrecording
class RemoveBadChannelsRecording(RecordingExtractor):

    preprocessor_name = 'RemoveBadChannels'
    installed = True  # check at class level if installed or not
    installation_mesg = ""  # err

    def __init__(self, recording, bad_channel_ids, bad_threshold, seconds, verbose):
        if not isinstance(recording, RecordingExtractor):
            raise ValueError("'recording' must be a RecordingExtractor")
        self._recording = recording
        self._bad_channel_ids = bad_channel_ids
        self._bad_threshold = bad_threshold
        self._seconds = seconds
        self.verbose = verbose
        self._initialize_subrecording_extractor()
        RecordingExtractor.__init__(self)
        self.copy_channel_properties(recording=self._subrecording)
        self.is_filtered = self._recording.is_filtered

        self._kwargs = {'recording': recording.make_serialized_dict(), 'bad_channel_ids': bad_channel_ids,
                        'bad_threshold': bad_threshold, 'seconds': seconds, 'verbose': verbose}

    def get_sampling_frequency(self):
        return self._subrecording.get_sampling_frequency()

    def get_num_frames(self):
        return self._subrecording.get_num_frames()

    def get_channel_ids(self):
        return self._subrecording.get_channel_ids()

    @check_get_traces_args
    def get_traces(self, channel_ids=None, start_frame=None, end_frame=None):
        traces = self._subrecording.get_traces(channel_ids=channel_ids, start_frame=start_frame, end_frame=end_frame)
        return traces

    def _initialize_subrecording_extractor(self):
        if isinstance(self._bad_channel_ids, (list, np.ndarray)):
            active_channels = []
            for chan in self._recording.get_channel_ids():
                if chan not in self._bad_channel_ids:
                    active_channels.append(chan)
            self._subrecording = SubRecordingExtractor(self._recording, channel_ids=active_channels)
        elif self._bad_channel_ids is None:
            start_frame = self._recording.get_num_frames() // 2
            end_frame = int(start_frame + self._seconds * self._recording.get_sampling_frequency())
            if end_frame > self._recording.get_num_frames():
                end_frame = self._recording.get_num_frames()
            traces = self._recording.get_traces(start_frame=start_frame, end_frame=end_frame)
            stds = np.std(traces, axis=1)
            bad_channel_ids = [ch for ch, std in enumerate(stds) if std > self._bad_threshold * np.median(stds)]
            if self.verbose:
                print('Automatically removing channels:', bad_channel_ids)
            active_channels = []
            for chan in self._recording.get_channel_ids():
                if chan not in bad_channel_ids:
                    active_channels.append(chan)
            self._subrecording = SubRecordingExtractor(self._recording, channel_ids=active_channels)
        else:
            self._subrecording = self._recording
        self.active_channels = self._subrecording.get_channel_ids()
Esempio n. 9
0
class RemoveBadChannelsRecording(RecordingExtractor):

    preprocessor_name = 'RemoveBadChannels'
    installed = True  # check at class level if installed or not
    preprocessor_gui_params = [
        {
            'name':
            'bad_channel_ids',
            'type':
            'int_list',
            'value':
            None,
            'default':
            None,
            'title':
            "List of bad channels. If None, automatic removal will be done based on standard deviation."
        },
        {
            'name':
            'bad_threshold',
            'type':
            'float',
            'title':
            "Threshold in number of sd to remove channels (when automatic)"
        },
        {
            'name':
            'seconds',
            'type':
            'float',
            'title':
            "Number of seconds to compute standard deviation (when automatic)"
        },
        {
            'name': 'verbose',
            'type': 'bool',
            'title': "If True output is verbose"
        },
    ]
    installation_mesg = ""  # err

    def __init__(self, recording, bad_channel_ids, bad_threshold, seconds,
                 verbose):
        if not isinstance(recording, RecordingExtractor):
            raise ValueError("'recording' must be a RecordingExtractor")
        self._recording = recording
        self._bad_channel_ids = bad_channel_ids
        self._bad_threshold = bad_threshold
        self._seconds = seconds
        self.verbose = verbose
        self._initialize_subrecording_extractor()
        RecordingExtractor.__init__(self)
        self.copy_channel_properties(recording=self._subrecording)

    def get_sampling_frequency(self):
        return self._subrecording.get_sampling_frequency()

    def get_num_frames(self):
        return self._subrecording.get_num_frames()

    def get_channel_ids(self):
        return self._subrecording.get_channel_ids()

    def get_traces(self, channel_ids=None, start_frame=None, end_frame=None):
        if start_frame is None:
            start_frame = 0
        if end_frame is None:
            end_frame = self.get_num_frames()
        if channel_ids is None:
            channel_ids = self.get_channel_ids()
        traces = self._subrecording.get_traces(channel_ids=channel_ids,
                                               start_frame=start_frame,
                                               end_frame=end_frame)
        return traces

    def _initialize_subrecording_extractor(self):
        if isinstance(self._bad_channel_ids, (list, np.ndarray)):
            active_channels = []
            for chan in self._recording.get_channel_ids():
                if chan not in self._bad_channel_ids:
                    active_channels.append(chan)
            self._subrecording = SubRecordingExtractor(
                self._recording, channel_ids=active_channels)
        elif self._bad_channel_ids is None:
            start_frame = self._recording.get_num_frames() // 2
            end_frame = int(start_frame + self._seconds *
                            self._recording.get_sampling_frequency())
            traces = self._recording.get_traces(start_frame=start_frame,
                                                end_frame=end_frame)
            stds = np.std(traces, axis=1)
            bad_channel_ids = [
                ch for ch, std in enumerate(stds)
                if std > self._bad_threshold * np.median(stds)
            ]
            if self.verbose:
                print('Automatically removing channels:', bad_channel_ids)
            active_channels = []
            for chan in self._recording.get_channel_ids():
                if chan not in bad_channel_ids:
                    active_channels.append(chan)
            self._subrecording = SubRecordingExtractor(
                self._recording, channel_ids=active_channels)
        else:
            self._subrecording = self._recording
        self.active_channels = self._subrecording.get_channel_ids()