Last active
August 16, 2023 17:56
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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