Source code for convnwb.objects.electrodes

"""Base electrodes class."""

from copy import deepcopy

from convnwb.io.utils import get_files, check_ext, check_folder
from convnwb.modutils.dependencies import safe_import, check_dependency

pd = safe_import('pandas')

###################################################################################################
###################################################################################################

class Bundle():
    """Object for collecting / managing a bundle definition."""

    def __init__(self, probe, hemisphere=None, lobe=None, region=None,
                 subregion=None, channels=None):
        """Initialize Bundle object."""

        self.probe = probe
        self.hemisphere = hemisphere
        self.lobe = lobe
        self.region = region
        self.subregion = subregion
        self.channels = channels

    def to_dict(self):
        """Export object information to a dictionary"""

        return {
            'probe' : self.probe,
            'hemisphere' : self.hemisphere,
            'lobe' : self.lobe,
            'region' : self.region,
            'subregion' : self.subregion,
            'channels' : self.channels,
        }


[docs]class Electrodes(): """Object for collecting / managing electrode information. Attributes ---------- subject : str Subject label. fs : int Sampling rate. bundles : list of Bundle Names of the bundles. """ n_electrodes_per_bundle = 8
[docs] def __init__(self, subject=None, fs=None): """Initialize Electrodes object.""" self.subject = subject self.fs = fs self.bundles = []
def __iter__(self): """Iterate across bundles in the object.""" for ind in range(self.n_bundles): yield self.bundles[ind] @property def n_bundles(self): """The number of bundles stored in the object.""" return len(self.bundles) @property def bundle_properties(self): """Access bundle property labels.""" if self.bundles: bundle_properties = list(self.bundles[0].to_dict().keys()) else: bundle_properties = [] return bundle_properties
[docs] def add_bundle(self, probe, hemisphere=None, lobe=None, region=None, subregion=None, channels=None): """Add a bundle to the object. Parameters ---------- probe : Bundle or str Name of the bundle, if string, or pre-initialized Bundle object. hemisphere : {'left', 'right'}, optional The hemisphere the probe is implanted in. lobe : {'frontal', 'parietal', 'temporal', 'occipital'}, optional Which lobe the probe is in. region : str, optional Location of the bundle. subregion : str, optional The subregion specifier of the probe. channels : list of int, optional A set of channel indices for the bundle. """ if isinstance(probe, Bundle): self.bundles.append(probe) else: self.bundles.append(Bundle(probe, hemisphere, lobe, region, subregion, channels))
[docs] def add_bundles(self, bundles): """Add multiple bundles to the object. Parameters ---------- names : Bundle or list of dict Names of the bundles. """ for bundle in bundles: if isinstance(bundle, Bundle): self.add_bundle(bundle) else: self.add_bundle(**bundle)
[docs] def get(self, field): """Get the values for a specified field from across all bundles. Parameters ---------- field : {'probe', 'hemisphere', 'lobe', 'region', 'subregion', 'channels'} Which field to get the values for. Returns ------- list Values for the specified field from across all defined bundles. """ return [getattr(bundle, field) for bundle in self.bundles]
[docs] def copy(self): """Return a deepcopy of this object.""" return deepcopy(self)
[docs] def to_dict(self, drop_empty=True): """Convert object data to a dictionary. Parameters ---------- drop_empty : bool, optional, default: True Whether to drops fields that are all None. """ labels = self.bundle_properties labels.remove('channels') out_dict = {label : [] for label in labels} for label in ['label', 'pin', 'channel']: out_dict[label] = [] for bundle in self.bundles: for ind in range(self.n_electrodes_per_bundle): out_dict['label'].append(bundle.probe + str(ind + 1)) out_dict['pin'].append(ind + 1) for label in labels: out_dict[label].append(getattr(bundle, label)) if bundle.channels is not None: out_dict['channel'].append(bundle.channels[ind]) else: out_dict['channel'].append(None) # Drop any entries in the dictionary conversion that are empty or all None if drop_empty: for dlabel in list(out_dict.keys()): if set(out_dict[dlabel]) == {None}: out_dict.pop(dlabel) return out_dict
[docs] @check_dependency(pd, 'pandas') def to_dataframe(self): """Return object data as a dataframe.""" return pd.DataFrame(self.to_dict())
[docs] @check_dependency(pd, 'pandas') def to_csv(self, file_name, folder=None, **kwargs): """Save out the electrode information as a CSV file. Parameters ---------- file_name : str The file name to save. folder : str The folder to save the file to. **kwargs Additional keyword arguments to pass to pd.DataFrame.to_csv(). """ self.to_dataframe().to_csv(check_ext(check_folder(file_name, folder), '.csv'), **kwargs)