Skip to content

Interface nwb

pynapple.io.interface_nwb

Pynapple class to interface with NWB files. Data are always lazy-loaded. Object behaves like dictionary.

NWBFile

Bases: UserDict

Class for reading NWB Files.

Examples:

>>> import pynapple as nap
>>> data = nap.load_file("my_file.nwb")
>>> data["units"]
  Index    rate  location      group
-------  ------  ----------  -------
      0    1.0  brain        0
      1    1.0  brain        0
      2    1.0  brain        0
Source code in pynapple/io/interface_nwb.py
class NWBFile(UserDict):
    """Class for reading NWB Files.


    Examples
    --------
    >>> import pynapple as nap
    >>> data = nap.load_file("my_file.nwb")
    >>> data["units"]
      Index    rate  location      group
    -------  ------  ----------  -------
          0    1.0  brain        0
          1    1.0  brain        0
          2    1.0  brain        0

    """

    _f_eval = {
        "IntervalSet": _make_interval_set,
        "Tsd": _make_tsd,
        "Ts": _make_ts,
        "TsdFrame": _make_tsd_frame,
        "TsdTensor": _make_tsd_tensor,
        "TsGroup": _make_tsgroup,
    }

    def __init__(self, file, lazy_loading=True):
        """
        Parameters
        ----------
        file : str or pynwb.file.NWBFile
            Valid file to a NWB file
        lazy_loading: bool
            If True return a memory-view of the data, load otherwise.

        Raises
        ------
        FileNotFoundError
            If path is invalid
        RuntimeError
            If file is not an instance of NWBFile
        """
        # TODO: do we really need to have instantiation from file and object in the same place?

        if isinstance(file, pynwb.file.NWBFile):
            self.nwb = file
            self.name = self.nwb.session_id
        else:
            path = Path(file)

            if path.exists():
                self.path = path
                self.name = path.stem
                self.io = NWBHDF5IO(path, "r")
                self.nwb = self.io.read()
            else:
                raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), file)

        self.data = _extract_compatible_data_from_nwbfile(self.nwb)
        self.key_to_id = {k: self.data[k]["id"] for k in self.data.keys()}

        self._view = [[k, self.data[k]["type"]] for k in self.data.keys()]

        self._lazy_loading = lazy_loading

        UserDict.__init__(self, self.data)

    def __str__(self):
        title = self.name if isinstance(self.name, str) else "-"
        headers = ["Keys", "Type"]
        return (
            title
            + "\n"
            + tabulate(self._view, headers=headers, tablefmt="mixed_outline")
        )

        # self._view = Table(title=self.name)
        # self._view.add_column("Keys", justify="left", style="cyan", no_wrap=True)
        # self._view.add_column("Type", style="green")
        # for k in self.data.keys():
        #     self._view.add_row(
        #         k,
        #         self.data[k]["type"],
        #     )

        # """View of the object"""
        # with Console() as console:
        #     console.print(self._view)
        # return ""

    def __repr__(self):
        """View of the object"""
        return self.__str__()

    def __getitem__(self, key):
        """Get object from NWB

        Parameters
        ----------
        key : str


        Returns
        -------
        (Ts, Tsd, TsdFrame, TsGroup, IntervalSet or dict of IntervalSet)


        Raises
        ------
        KeyError
            If key is not in the dictionary
        """
        if key.__hash__:
            if self.__contains__(key):
                if isinstance(self.data[key], dict) and "id" in self.data[key]:
                    obj = self.nwb.objects[self.data[key]["id"]]
                    try:
                        data = self._f_eval[self.data[key]["type"]](
                            obj, lazy_loading=self._lazy_loading
                        )
                    except Exception:
                        warnings.warn(
                            "Failed to build {}.\n Returning the NWB object for manual inspection".format(
                                self.data[key]["type"]
                            ),
                            stacklevel=2,
                        )
                        data = obj

                    self.data[key] = data
                    return data
                else:
                    return self.data[key]
            else:
                raise KeyError("Can't find key {} in group index.".format(key))

    def close(self):
        """Close the NWB file"""
        self.io.close()

__init__

__init__(file, lazy_loading=True)

Parameters:

Name Type Description Default
file str or NWBFile

Valid file to a NWB file

required
lazy_loading

If True return a memory-view of the data, load otherwise.

True

Raises:

Type Description
FileNotFoundError

If path is invalid

RuntimeError

If file is not an instance of NWBFile

Source code in pynapple/io/interface_nwb.py
def __init__(self, file, lazy_loading=True):
    """
    Parameters
    ----------
    file : str or pynwb.file.NWBFile
        Valid file to a NWB file
    lazy_loading: bool
        If True return a memory-view of the data, load otherwise.

    Raises
    ------
    FileNotFoundError
        If path is invalid
    RuntimeError
        If file is not an instance of NWBFile
    """
    # TODO: do we really need to have instantiation from file and object in the same place?

    if isinstance(file, pynwb.file.NWBFile):
        self.nwb = file
        self.name = self.nwb.session_id
    else:
        path = Path(file)

        if path.exists():
            self.path = path
            self.name = path.stem
            self.io = NWBHDF5IO(path, "r")
            self.nwb = self.io.read()
        else:
            raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), file)

    self.data = _extract_compatible_data_from_nwbfile(self.nwb)
    self.key_to_id = {k: self.data[k]["id"] for k in self.data.keys()}

    self._view = [[k, self.data[k]["type"]] for k in self.data.keys()]

    self._lazy_loading = lazy_loading

    UserDict.__init__(self, self.data)

__repr__

__repr__()

View of the object

Source code in pynapple/io/interface_nwb.py
def __repr__(self):
    """View of the object"""
    return self.__str__()

__getitem__

__getitem__(key)

Get object from NWB

Parameters:

Name Type Description Default
key str
required

Returns:

Type Description
(Ts, Tsd, TsdFrame, TsGroup, IntervalSet or dict of IntervalSet)

Raises:

Type Description
KeyError

If key is not in the dictionary

Source code in pynapple/io/interface_nwb.py
def __getitem__(self, key):
    """Get object from NWB

    Parameters
    ----------
    key : str


    Returns
    -------
    (Ts, Tsd, TsdFrame, TsGroup, IntervalSet or dict of IntervalSet)


    Raises
    ------
    KeyError
        If key is not in the dictionary
    """
    if key.__hash__:
        if self.__contains__(key):
            if isinstance(self.data[key], dict) and "id" in self.data[key]:
                obj = self.nwb.objects[self.data[key]["id"]]
                try:
                    data = self._f_eval[self.data[key]["type"]](
                        obj, lazy_loading=self._lazy_loading
                    )
                except Exception:
                    warnings.warn(
                        "Failed to build {}.\n Returning the NWB object for manual inspection".format(
                            self.data[key]["type"]
                        ),
                        stacklevel=2,
                    )
                    data = obj

                self.data[key] = data
                return data
            else:
                return self.data[key]
        else:
            raise KeyError("Can't find key {} in group index.".format(key))

close

close()

Close the NWB file

Source code in pynapple/io/interface_nwb.py
def close(self):
    """Close the NWB file"""
    self.io.close()