Created
October 9, 2023 21:44
-
-
Save rly/be7bee420b482b9ddcd084f57cc4115e to your computer and use it in GitHub Desktop.
Tests on what is currently possible for modifying an NWB file using PyNWB and h5py
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": "markdown", | |
"id": "16bb28b1-b0d2-4bbb-b653-5582d2035f1d", | |
"metadata": {}, | |
"source": [ | |
"# Tests on what is currently possible for modifying an NWB file using PyNWB and h5py\n", | |
"As of October 9, 2023 (pynwb==2.5.0, h5py==3.9.0)." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"id": "584267c6-26f9-437d-89f4-33468c9471eb", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from importlib.metadata import version\n", | |
"import h5py" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"id": "9e381f78-8547-44e4-a5d9-2ec2504aa420", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'2.5.0+0.g68c4f564.dirty'" | |
] | |
}, | |
"execution_count": 2, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"version(\"pynwb\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"id": "00481fa7-f067-49cc-b657-a4ce825c1009", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'3.9.0'" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"version(\"h5py\")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "5ba6045c-a653-4c4f-8654-1d51e0a38251", | |
"metadata": {}, | |
"source": [ | |
"## Create a test NWB file" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"id": "1e59db94-e8c0-4c91-b0c4-6c253eb0b560", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from pynwb import NWBFile, NWBHDF5IO, TimeSeries\n", | |
"import datetime\n", | |
"import numpy as np" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"id": "d574d3a5-2c64-4fe0-9ee6-ce8cf86d33cd", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"filename = \"test_modify.nwb\"\n", | |
"def create_test_file(my_filename):\n", | |
" nwbfile = NWBFile(\n", | |
" session_description=\"session_description\",\n", | |
" identifier=\"identifier\",\n", | |
" session_start_time=datetime.datetime.now(datetime.timezone.utc),\n", | |
" )\n", | |
" \n", | |
" ts = TimeSeries(\n", | |
" name=\"test_timeseries\",\n", | |
" data=np.array([1, 2, 3]),\n", | |
" timestamps=np.array([0.1, 0.2, 0.3]),\n", | |
" unit=\"m\"\n", | |
" )\n", | |
" nwbfile.add_acquisition(ts)\n", | |
" \n", | |
" filename = \"test_modify.nwb\"\n", | |
" \n", | |
" with NWBHDF5IO(my_filename, \"w\") as io:\n", | |
" io.write(nwbfile)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "b1ddf0c7-eb03-4d6b-a13a-08780446cbc7", | |
"metadata": {}, | |
"source": [ | |
"## Attributes" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "60582875-af8e-45a3-bfac-620228f274d9", | |
"metadata": {}, | |
"source": [ | |
"### Modify an attribute using PyNWB - not allowed because python object attribute is already set" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"id": "67c0b78a-aad4-47f6-b752-f3e44bb2c5f5", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"create_test_file(filename)\n", | |
"with NWBHDF5IO(filename, \"a\") as io:\n", | |
" nwbfile = io.read()\n", | |
" # raises AttributeError: can't set attribute 'unit' -- already set\n", | |
" # nwbfile.acquisition[\"test_timeseries\"].unit = \"new unit\"\n", | |
" # io.write(nwbfile)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "799df494-5d17-40a7-a012-86f7b55061b8", | |
"metadata": {}, | |
"source": [ | |
"### Modify an attribute using h5py - allowed" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"id": "99e85ab5-3e15-413b-8114-14a5616b1b8f", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"m\n", | |
"new unit\n" | |
] | |
} | |
], | |
"source": [ | |
"create_test_file(filename)\n", | |
"with h5py.File(filename, \"a\") as f:\n", | |
" print(f[\"/acquisition/test_timeseries/data\"].attrs[\"unit\"])\n", | |
" f[\"/acquisition/test_timeseries/data\"].attrs[\"unit\"] = \"new unit\"\n", | |
" print(f[\"/acquisition/test_timeseries/data\"].attrs[\"unit\"])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"id": "67a79b4e-768d-4a6c-b602-e503daa98991", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"new unit\n" | |
] | |
} | |
], | |
"source": [ | |
"with NWBHDF5IO(filename, \"r\") as io:\n", | |
" nwbfile = io.read()\n", | |
" print(nwbfile.acquisition[\"test_timeseries\"].unit)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "7fc9abd6-17a4-412a-afd4-46676c760249", | |
"metadata": {}, | |
"source": [ | |
"### Modify an attribute using h5py and change its dtype - allowed" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"id": "a8d55f6f-148b-4e1d-9969-cfcf2a0ac8e5", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"m\n", | |
"123\n" | |
] | |
} | |
], | |
"source": [ | |
"create_test_file(filename)\n", | |
"with h5py.File(filename, \"a\") as f:\n", | |
" print(f[\"/acquisition/test_timeseries/data\"].attrs[\"unit\"])\n", | |
" f[\"/acquisition/test_timeseries/data\"].attrs[\"unit\"] = 123\n", | |
" print(f[\"/acquisition/test_timeseries/data\"].attrs[\"unit\"])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"id": "76e91b99-3106-4c95-b62f-50bf8288afa8", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# this will raise a ConstructError because the dtype of unit is not the expected dtype\n", | |
"# with NWBHDF5IO(filename, \"r\") as io:\n", | |
"# nwbfile = io.read()\n", | |
"# print(nwbfile.acquisition[\"test_timeseries\"].unit)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "128b36a9-fb19-42e2-85f0-56eb420177c5", | |
"metadata": {}, | |
"source": [ | |
"### Create a new attribute using PyNWB - no effect" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"id": "47466232-c5f8-4c9d-b877-4fb1637600ce", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"None\n", | |
"continuous\n" | |
] | |
} | |
], | |
"source": [ | |
"create_test_file(filename)\n", | |
"with NWBHDF5IO(filename, \"a\") as io:\n", | |
" nwbfile = io.read()\n", | |
" print(nwbfile.acquisition[\"test_timeseries\"].continuity)\n", | |
" nwbfile.acquisition[\"test_timeseries\"].continuity = \"continuous\"\n", | |
" print(nwbfile.acquisition[\"test_timeseries\"].continuity)\n", | |
" nwbfile.acquisition[\"test_timeseries\"].set_modified()\n", | |
" io.write(nwbfile)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"id": "a380aa86-6214-4585-a88f-203713d6a34e", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"None\n" | |
] | |
} | |
], | |
"source": [ | |
"with NWBHDF5IO(filename, \"r\") as io:\n", | |
" nwbfile = io.read()\n", | |
" print(nwbfile.acquisition[\"test_timeseries\"].continuity)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "66546936-8168-47d3-8e44-2441dd018e9b", | |
"metadata": {}, | |
"source": [ | |
"### Create a new attribute using h5py - allowed" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"id": "3ee7141f-de85-4ccf-ae67-faa3031b5f49", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"False\n", | |
"continuous\n" | |
] | |
} | |
], | |
"source": [ | |
"create_test_file(filename)\n", | |
"with h5py.File(filename, \"a\") as f:\n", | |
" print(\"continuity\" in f[\"/acquisition/test_timeseries/data\"].attrs)\n", | |
" f[\"/acquisition/test_timeseries/data\"].attrs[\"continuity\"] = \"continuous\"\n", | |
" print(f[\"/acquisition/test_timeseries/data\"].attrs[\"continuity\"])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"id": "281298af-afb9-4fad-8b0f-b83865f8bc5d", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"continuous\n" | |
] | |
} | |
], | |
"source": [ | |
"with NWBHDF5IO(filename, \"r\") as io:\n", | |
" nwbfile = io.read()\n", | |
" print(nwbfile.acquisition[\"test_timeseries\"].continuity)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "b7ac9abb-a561-40fe-9b6d-561f4acf45b2", | |
"metadata": {}, | |
"source": [ | |
"### Delete an attribute using PyNWB - not possible" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"id": "b252b7e8-f9cc-4490-b3c1-684c0e78e892", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"no description\n", | |
"no description\n" | |
] | |
} | |
], | |
"source": [ | |
"create_test_file(filename)\n", | |
"with NWBHDF5IO(filename, \"a\") as io:\n", | |
" nwbfile = io.read()\n", | |
" print(nwbfile.acquisition[\"test_timeseries\"].description)\n", | |
" nwbfile.acquisition[\"test_timeseries\"].description = None\n", | |
" # del nwbfile.acquisition[\"test_timeseries\"].description # raises AttributeError\n", | |
" print(nwbfile.acquisition[\"test_timeseries\"].description)\n", | |
" nwbfile.acquisition[\"test_timeseries\"].set_modified()\n", | |
" io.write(nwbfile)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "ce4b67ef-de51-499d-90b0-4061c61f5ac0", | |
"metadata": {}, | |
"source": [ | |
"### Delete an attribute using h5py - allowed" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"id": "525906a6-cd0b-4ac1-9dfc-184e5cef250a", | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"no description\n", | |
"False\n" | |
] | |
} | |
], | |
"source": [ | |
"create_test_file(filename)\n", | |
"with h5py.File(filename, \"a\") as f:\n", | |
" print(f[\"/acquisition/test_timeseries\"].attrs[\"description\"])\n", | |
" del f[\"/acquisition/test_timeseries\"].attrs[\"description\"]\n", | |
" print(\"description\" in f[\"/acquisition/test_timeseries\"].attrs)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"id": "e5b0c3bd-ba99-4f3c-98ec-e3f7a7100be0", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"False\n" | |
] | |
} | |
], | |
"source": [ | |
"# NOTE: reading the file in PyNWB will see that description is not set and load the default\n", | |
"# value from the schema \"no description\", so here we read using h5py\n", | |
"with h5py.File(filename, \"r\") as f:\n", | |
" print(\"description\" in f[\"/acquisition/test_timeseries\"].attrs)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "20460697-9dd8-4498-a0c8-0d76d6103b22", | |
"metadata": {}, | |
"source": [ | |
"## Datasets" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "bcdcf17f-66d6-405e-8580-0763ff9c11fe", | |
"metadata": {}, | |
"source": [ | |
"## Groups" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "fdcbef92-b1ed-45d3-90db-468bddcce49c", | |
"metadata": {}, | |
"source": [ | |
"## Links" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "bef77b36-307c-45ab-a0e6-4e800fba10d0", | |
"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