Skip to content

Instantly share code, notes, and snippets.

@rly
Last active August 16, 2023 17:56
Show Gist options
  • Save rly/3622b3a709874f9ad5c2f411f3c86f84 to your computer and use it in GitHub Desktop.
Save rly/3622b3a709874f9ad5c2f411f3c86f84 to your computer and use it in GitHub Desktop.
Get the versions of the namespaces/extensions cached in an NWB file or used by PyNWB
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "bd63f12d-68f1-4792-9724-ebfb843bba56",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/Users/rly/Downloads/20230622_155936 (1).nwb\n",
"Namespaces cached in this file:\n",
"\t core 2.5.0\n",
"\t hdmf-common 1.6.0\n",
"\t hdmf-experimental 0.3.0\n",
"\t ndx-franklab-novela 0.1.0\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/rly/Documents/NWB/hdmf/src/hdmf/spec/namespace.py:531: UserWarning: Ignoring cached namespace 'hdmf-common' version 1.6.0 because version 1.8.0 is already loaded.\n",
" warn(\"Ignoring cached namespace '%s' version %s because version %s is already loaded.\"\n",
"/Users/rly/Documents/NWB/hdmf/src/hdmf/spec/namespace.py:531: UserWarning: Ignoring cached namespace 'core' version 2.5.0 because version 2.6.0-alpha is already loaded.\n",
" warn(\"Ignoring cached namespace '%s' version %s because version %s is already loaded.\"\n",
"/Users/rly/Documents/NWB/hdmf/src/hdmf/spec/namespace.py:531: UserWarning: Ignoring cached namespace 'hdmf-experimental' version 0.3.0 because version 0.5.0 is already loaded.\n",
" warn(\"Ignoring cached namespace '%s' version %s because version %s is already loaded.\"\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Namespaces loaded by PyNWB when loading this file:\n",
"\t core 2.6.0-alpha\n",
"\t hdmf-common 1.8.0\n",
"\t hdmf-experimental 0.5.0\n",
"\t ndx-franklab-novela 0.1.0\n",
"\n",
"/Users/rly/Documents/NWB_Data/dandisets/000409/sub-CSHL047_ses-b52182e7-39f6-4914-9717-136db589706e_behavior+ecephys+image.nwb\n",
"Namespaces cached in this file:\n",
"\t core 2.5.0\n",
"\t hdmf-common 1.5.1\n",
"\t hdmf-experimental 0.2.0\n",
"\t ndx-ibl 0.1.0\n",
"\t ndx-pose 0.1.1\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/rly/Documents/NWB/hdmf/src/hdmf/spec/namespace.py:531: UserWarning: Ignoring cached namespace 'hdmf-common' version 1.5.1 because version 1.8.0 is already loaded.\n",
" warn(\"Ignoring cached namespace '%s' version %s because version %s is already loaded.\"\n",
"/Users/rly/Documents/NWB/hdmf/src/hdmf/spec/namespace.py:531: UserWarning: Ignoring cached namespace 'hdmf-experimental' version 0.2.0 because version 0.5.0 is already loaded.\n",
" warn(\"Ignoring cached namespace '%s' version %s because version %s is already loaded.\"\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Namespaces loaded by PyNWB when loading this file:\n",
"\t core 2.6.0-alpha\n",
"\t hdmf-common 1.8.0\n",
"\t hdmf-experimental 0.5.0\n",
"\t ndx-ibl 0.1.0\n",
"\t ndx-pose 0.1.1\n",
"\n",
"/Users/rly/Downloads/20230622_155936 (1).nwb\n",
"Namespaces cached in this file:\n",
"\t core 2.5.0\n",
"\t hdmf-common 1.6.0\n",
"\t hdmf-experimental 0.3.0\n",
"\t ndx-franklab-novela 0.1.0\n",
"Namespaces loaded by PyNWB when loading this file:\n",
"\t core 2.6.0-alpha\n",
"\t hdmf-common 1.8.0\n",
"\t hdmf-experimental 0.5.0\n",
"\t ndx-franklab-novela 0.1.0\n",
"\n"
]
}
],
"source": [
"from pynwb import get_type_map, NWBHDF5IO\n",
"from hdmf.build import TypeMap\n",
"from hdmf.spec import NamespaceCatalog\n",
"from pynwb.spec import NWBDatasetSpec, NWBGroupSpec, NWBNamespace\n",
"\n",
"paths = [\n",
" \"/Users/rly/Downloads/20230622_155936 (1).nwb\",\n",
" \"/Users/rly/Documents/NWB_Data/dandisets/000409/sub-CSHL047_ses-b52182e7-39f6-4914-9717-136db589706e_behavior+ecephys+image.nwb\",\n",
" \"/Users/rly/Downloads/20230622_155936 (1).nwb\",\n",
"]\n",
"for path in paths:\n",
" print(path)\n",
"\n",
" # 1) get namespaces that are in the file\n",
" \n",
" # get a new type map with no namespaces\n",
" tm = TypeMap(NamespaceCatalog(NWBGroupSpec, NWBDatasetSpec, NWBNamespace))\n",
" NWBHDF5IO.load_namespaces(tm, path) #, file=file_obj, driver=driver)\n",
" namespaces = tm.namespace_catalog.namespaces\n",
" print(\"Namespaces cached in this file:\")\n",
" for ns in sorted(namespaces):\n",
" print(\"\\t\", ns, tm.namespace_catalog.get_namespace(ns)[\"version\"])\n",
"\n",
" # 2) get namespaces that would be used by pynwb\n",
" \n",
" # if the namespace version loaded by pynwb is greater than the one\n",
" # cached in the file, then the namespace loaded by pynwb will be used\n",
" # (and a warning will be raised).\n",
" # else, the namespace cached in the file will be used.\n",
" \n",
" # get a new copy of the default type map loaded by pynwb\n",
" # NOTE that pynwb.load_namespaces(yaml_file) (if called) affects this \n",
" # loaded type map \n",
" tm = get_type_map()\n",
" NWBHDF5IO.load_namespaces(tm, path) #, file=file_obj, driver=driver)\n",
" namespaces = tm.namespace_catalog.namespaces\n",
" print(\"Namespaces loaded by PyNWB when loading this file:\")\n",
" for ns in sorted(namespaces):\n",
" print(\"\\t\", ns, tm.namespace_catalog.get_namespace(ns)[\"version\"])\n",
"\n",
" # 3) same as 2 but using NWBHDF5IO. takes about the same amount of time\n",
" # io = NWBHDF5IO(path, \"r\", load_namespaces=True)\n",
" # namespaces = io.manager.type_map.namespace_catalog.namespaces\n",
" # print(\"Namespaces loaded by PyNWB when loading this file:\")\n",
" # for ns in sorted(namespaces):\n",
" # print(\"\\t\", ns, tm.namespace_catalog.get_namespace(ns)[\"version\"])\n",
"\n",
" print()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "0cf2f5de-c4ea-4d38-bcdc-b9c92d2c6126",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/Users/rly/Downloads/20230622_155936 (1).nwb\n",
"Namespaces cached in this file:\n",
"\t core ('2.5.0',)\n",
"\t hdmf-common ('1.6.0',)\n",
"\t hdmf-experimental ('0.3.0',)\n",
"\t ndx-franklab-novela ('0.1.0',)\n",
"\n",
"/Users/rly/Documents/NWB_Data/dandisets/000409/sub-CSHL047_ses-b52182e7-39f6-4914-9717-136db589706e_behavior+ecephys+image.nwb\n",
"Namespaces cached in this file:\n",
"\t core ('2.5.0',)\n",
"\t hdmf-common ('1.5.1',)\n",
"\t hdmf-experimental ('0.2.0',)\n",
"\t ndx-ibl ('0.1.0',)\n",
"\t ndx-pose ('0.1.1',)\n",
"\n",
"/Users/rly/Downloads/20230622_155936 (1).nwb\n",
"Namespaces cached in this file:\n",
"\t core ('2.5.0',)\n",
"\t hdmf-common ('1.6.0',)\n",
"\t hdmf-experimental ('0.3.0',)\n",
"\t ndx-franklab-novela ('0.1.0',)\n",
"\n"
]
}
],
"source": [
"# using h5py is significantly faster to read the cached namespace versions\n",
"# if you do not need to parse and resolve the spec\n",
"import h5py\n",
"\n",
"def get_extension_versions(path: str) -> dict[str, tuple]:\n",
" # TODO first check whether this is an HDF5 file\n",
" file = h5py.File(path, \"r\")\n",
" ret = dict()\n",
" for ns_name in file[\"specifications\"].keys():\n",
" ret[ns_name] = tuple(file[\"specifications\"][ns_name].keys())\n",
" return ret\n",
"\n",
"for path in paths:\n",
" print(path)\n",
" ver = get_extension_versions(path)\n",
" \n",
" print(\"Namespaces cached in this file:\")\n",
" for ns_name, ns_versions in ver.items():\n",
" print(\"\\t\", ns_name, ns_versions)\n",
"\n",
" print()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9b59b475-300c-413c-a0b1-53e240ff473e",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment