Skip to content

Instantly share code, notes, and snippets.

@rly
Last active July 25, 2023 14:12
Show Gist options
  • Save rly/6aac3d9006ab9127bf39fc21938f5afb to your computer and use it in GitHub Desktop.
Save rly/6aac3d9006ab9127bf39fc21938f5afb to your computer and use it in GitHub Desktop.
Function to return all PyNWB objects in the file that are instances of the neurodata_type class
from pynwb import NWBHDF5IO, NWBFile
def get_neurodata_type_objs_io(io: NWBHDF5IO, neurodata_type: str, namespace: str):
"""Return all PyNWB objects in the file that have a neurodata type from a namespace.
This works regardless of whether the extension was imported earlier in the python execution.
All objects that are instances of the class associated with the given neurodata_type in the
given namespace will be returned. This includes objects that are instances of a subclass.
For example, if an extension defines a new neurodata type OnePhotonSeries that extends
ImageSeries, then `get_neurodata_type_objects_in_file(io, "ImageSeries", "core")` will
include all OnePhotonSeries objects.
.. code-block:: python
from pynwb import NWBHDF5IO
with NWBHDF5IO(filepath, mode="r", load_namespaces=True) as io:
obj_list = get_neurodata_type_objs_io(io, "Subject", "core")
"""
# if the extension python module has been imported, this line will return the custom API
# class defined in the extension (my.extension.module.path.class_name).
# otherwise, this line will return the class generated for reading data with this
# neurodata type based on the cached namespace in the file (abc.class_name).
pynwb_cls = io.manager.type_map.get_dt_container_cls(neurodata_type, namespace)
read_nwbfile = io.read()
return get_neurodata_type_objs(read_nwbfile, pynwb_cls)
def get_neurodata_type_objs(nwbfile: NWBFile, pynwb_class: type):
"""Return all PyNWB objects in the file that are instances of the pynwb_class class.
This includes objects that are instances of a subclass.
.. code-block:: python
from pynwb import ImageSeries
obj_list = get_neurodata_type_objects(nwbfile, ImageSeries)
"""
ret = [obj for obj in nwbfile.objects.values() if isinstance(obj, pynwb_class)]
return ret
def print_obj_info(io: NWBHDF5IO, obj_list: list):
for i, obj in enumerate(obj_list):
builder = io.manager.get_builder(obj)
print("%d: %s '%s'" % (i, type(obj), obj.name))
print("\tObject ID: %s" % obj.object_id)
print("\tHDF5 path: %s" % builder.path)
if __name__ == "__main__":
# an example data file downloaded from dandiset 000021 that has an extension to the Subject neurodata type
filepath = "/Users/rly/Documents/NWB_Data/dandisets/000021/sub-699733573_ses-715093703_probe-810755797_ecephys.nwb"
with NWBHDF5IO(filepath, mode="r", load_namespaces=True) as io:
# two different approaches to getting the objects
# 1) by IO object, neurodata type, and namespace
obj_list = get_neurodata_type_objs_io(io, "EcephysSpecimen", "ndx-aibs-ecephys")
print_obj_info(io, obj_list)
# because ndx-aibs-ecephys.EcephysSpecimen extends core.Subject, the following will return the same objects
obj_list = get_neurodata_type_objs_io(io, "Subject", "core")
print_obj_info(io, obj_list)
# 2) by NWBFile object and PyNWB class
from pynwb.file import Subject
# because ndx-aibs-ecephys.EcephysSpecimen extends core.Subject, the following will return the same objects
nwbfile = io.read()
obj_list = get_neurodata_type_objs(nwbfile, Subject)
print_obj_info(io, obj_list)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment