././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5580275 pynwb-2.5.0/0000755000175100001730000000000014467767767012315 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/Legal.txt0000644000175100001730000000150714467767506014074 0ustar00runnerdocker“pynwb” Copyright (c) 2017-2023, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. If you have questions about your rights to use or distribute this software, please contact Berkeley Lab's Innovation & Partnerships Office at IPO@lbl.gov. NOTICE. This Software was developed under funding from the U.S. Department of Energy and the U.S. Government consequently retains certain rights. As such, the U.S. Government has been granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software to reproduce, distribute copies to the public, prepare derivative works, and perform publicly and display publicly, and to permit other to do so. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/MANIFEST.in0000644000175100001730000000034614467767506014045 0ustar00runnerdockerinclude license.txt Legal.txt versioneer.py src/pynwb/_version.py src/pynwb/_due.py include requirements.txt requirements-dev.txt requirements-doc.txt requirements-min.txt environment-ros3.yml include test.py tox.ini graft tests ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5580275 pynwb-2.5.0/PKG-INFO0000644000175100001730000002142114467767767013412 0ustar00runnerdockerMetadata-Version: 2.1 Name: pynwb Version: 2.5.0 Summary: Package for working with Neurodata stored in the NWB format Home-page: https://github.com/NeurodataWithoutBorders/pynwb Author: Andrew Tritt Author-email: ajtritt@lbl.gov License: BSD Keywords: Neuroscience python HDF HDF5 cross-platform open-data data-format open-source open-science reproducible-research PyNWB NWB NWB:N NeurodataWithoutBorders Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: License :: OSI Approved :: BSD License Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research Classifier: Operating System :: Microsoft :: Windows Classifier: Operating System :: MacOS Classifier: Operating System :: Unix Classifier: Topic :: Scientific/Engineering :: Medical Science Apps. Requires-Python: >=3.8 Description-Content-Type: text/x-rst; charset=UTF-8 .. image:: docs/source/figures/logo_pynwb.png :width: 200px PyNWB is a Python package for working with NWB files. The PyNWB documentation can be found at https://pynwb.readthedocs.io Latest Release ============== .. image:: https://badge.fury.io/py/pynwb.svg :target: https://badge.fury.io/py/pynwb .. image:: https://anaconda.org/conda-forge/pynwb/badges/version.svg :target: https://anaconda.org/conda-forge/pynwb Code Coverage ============== .. image:: https://github.com/NeurodataWithoutBorders/pynwb/workflows/Run%20coverage/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions?query=workflow%3A%22Run+coverage%22 Overall test coverage .. image:: https://codecov.io/gh/NeurodataWithoutBorders/pynwb/branch/dev/graph/badge.svg :target: https://codecov.io/gh/NeurodataWithoutBorders/pynwb Unit test coverage .. image:: https://codecov.io/gh/NeurodataWithoutBorders/pynwb/branch/dev/graph/badge.svg?flag=unit :target: https://codecov.io/gh/NeurodataWithoutBorders/pynwb Integration test coverage .. image:: https://codecov.io/gh/NeurodataWithoutBorders/pynwb/branch/dev/graph/badge.svg?flag=integration :target: https://codecov.io/gh/NeurodataWithoutBorders/pynwb Overall Health ============== .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_tests.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_tests.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_flake8.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_flake8.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/check_external_links.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/check_external_links.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_inspector_tests.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_inspector_tests.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_all_tests.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_all_tests.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/deploy_release.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/deploy_release.yml .. image:: https://readthedocs.org/projects/pynwb/badge/?version=latest :target: https://pynwb.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status .. image:: https://img.shields.io/pypi/l/pynwb.svg :target: https://github.com/neurodatawithoutborders/pynwb/blob/dev/license.txt :alt: PyPI - License **Conda** .. image:: https://circleci.com/gh/conda-forge/pynwb-feedstock.svg?style=shield :target: https://circleci.com/gh/conda-forge/pynwb-feedstock :alt: Conda Feedstock Status NWB Format API ============== PyNWB is a Python package for working with NWB files. It provides a high-level API for efficiently working with Neurodata stored in the `NWB format `_. `Neurodata Without Borders (NWB) `_ is a project to develop a unified data format for cellular-based neurophysiology data, focused on the dynamics of groups of neurons measured under a large range of experimental conditions. The NWB team consists of neuroscientists and software developers who recognize that adoption of a unified data format is an important step toward breaking down the barriers to data sharing in neuroscience. Installation ============ See the PyNWB documentation for details https://pynwb.readthedocs.io/en/stable/install_users.html Code of Conduct =============== This project and everyone participating in it is governed by our `code of conduct guidelines <.github/CODE_OF_CONDUCT.rst>`_. By participating, you are expected to uphold this code. Contributing ============ For details on how to contribute to PyNWB see our `contribution guidelines `_. Citing NWB ========== * **Manuscript:** Oliver Rübel, Andrew Tritt, Ryan Ly, Benjamin K Dichter, Satrajit Ghosh, Lawrence Niu, Pamela Baker, Ivan Soltesz, Lydia Ng, Karel Svoboda, Loren Frank, Kristofer E Bouchard. (2022). The Neurodata Without Borders ecosystem for neurophysiological data science. eLife, 11:e78362. doi: https://doi.org/10.7554/eLife.78362 * **RRID:** (PyNWB, RRID:SCR_017452) LICENSE ======= "pynwb" Copyright (c) 2017-2023, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, U.S. Dept. of Energy nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You are under no obligation whatsoever to provide any bug fixes, patches, or upgrades to the features, functionality or performance of the source code ("Enhancements") to anyone; however, if you choose to make your Enhancements available either publicly, or directly to Lawrence Berkeley National Laboratory, without imposing a separate written license agreement for such Enhancements, then you hereby grant the following license: a non-exclusive, royalty-free perpetual license to install, use, modify, prepare derivative works, incorporate into other computer software, distribute, and sublicense such enhancements or derivative works thereof, in binary and source code form. COPYRIGHT ========= "pynwb" Copyright (c) 2017-2023, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. If you have questions about your rights to use or distribute this software, please contact Berkeley Lab's Innovation & Partnerships Office at IPO@lbl.gov. NOTICE. This Software was developed under funding from the U.S. Department of Energy and the U.S. Government consequently retains certain rights. As such, the U.S. Government has been granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software to reproduce, distribute copies to the public, prepare derivative works, and perform publicly and display publicly, and to permit other to do so. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/README.rst0000644000175100001730000001725514467767506014005 0ustar00runnerdocker.. image:: docs/source/figures/logo_pynwb.png :width: 200px PyNWB is a Python package for working with NWB files. The PyNWB documentation can be found at https://pynwb.readthedocs.io Latest Release ============== .. image:: https://badge.fury.io/py/pynwb.svg :target: https://badge.fury.io/py/pynwb .. image:: https://anaconda.org/conda-forge/pynwb/badges/version.svg :target: https://anaconda.org/conda-forge/pynwb Code Coverage ============== .. image:: https://github.com/NeurodataWithoutBorders/pynwb/workflows/Run%20coverage/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions?query=workflow%3A%22Run+coverage%22 Overall test coverage .. image:: https://codecov.io/gh/NeurodataWithoutBorders/pynwb/branch/dev/graph/badge.svg :target: https://codecov.io/gh/NeurodataWithoutBorders/pynwb Unit test coverage .. image:: https://codecov.io/gh/NeurodataWithoutBorders/pynwb/branch/dev/graph/badge.svg?flag=unit :target: https://codecov.io/gh/NeurodataWithoutBorders/pynwb Integration test coverage .. image:: https://codecov.io/gh/NeurodataWithoutBorders/pynwb/branch/dev/graph/badge.svg?flag=integration :target: https://codecov.io/gh/NeurodataWithoutBorders/pynwb Overall Health ============== .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_tests.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_tests.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_flake8.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_flake8.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/check_external_links.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/check_external_links.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_inspector_tests.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_inspector_tests.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_all_tests.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_all_tests.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/deploy_release.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/deploy_release.yml .. image:: https://readthedocs.org/projects/pynwb/badge/?version=latest :target: https://pynwb.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status .. image:: https://img.shields.io/pypi/l/pynwb.svg :target: https://github.com/neurodatawithoutborders/pynwb/blob/dev/license.txt :alt: PyPI - License **Conda** .. image:: https://circleci.com/gh/conda-forge/pynwb-feedstock.svg?style=shield :target: https://circleci.com/gh/conda-forge/pynwb-feedstock :alt: Conda Feedstock Status NWB Format API ============== PyNWB is a Python package for working with NWB files. It provides a high-level API for efficiently working with Neurodata stored in the `NWB format `_. `Neurodata Without Borders (NWB) `_ is a project to develop a unified data format for cellular-based neurophysiology data, focused on the dynamics of groups of neurons measured under a large range of experimental conditions. The NWB team consists of neuroscientists and software developers who recognize that adoption of a unified data format is an important step toward breaking down the barriers to data sharing in neuroscience. Installation ============ See the PyNWB documentation for details https://pynwb.readthedocs.io/en/stable/install_users.html Code of Conduct =============== This project and everyone participating in it is governed by our `code of conduct guidelines <.github/CODE_OF_CONDUCT.rst>`_. By participating, you are expected to uphold this code. Contributing ============ For details on how to contribute to PyNWB see our `contribution guidelines `_. Citing NWB ========== * **Manuscript:** Oliver Rübel, Andrew Tritt, Ryan Ly, Benjamin K Dichter, Satrajit Ghosh, Lawrence Niu, Pamela Baker, Ivan Soltesz, Lydia Ng, Karel Svoboda, Loren Frank, Kristofer E Bouchard. (2022). The Neurodata Without Borders ecosystem for neurophysiological data science. eLife, 11:e78362. doi: https://doi.org/10.7554/eLife.78362 * **RRID:** (PyNWB, RRID:SCR_017452) LICENSE ======= "pynwb" Copyright (c) 2017-2023, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, U.S. Dept. of Energy nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You are under no obligation whatsoever to provide any bug fixes, patches, or upgrades to the features, functionality or performance of the source code ("Enhancements") to anyone; however, if you choose to make your Enhancements available either publicly, or directly to Lawrence Berkeley National Laboratory, without imposing a separate written license agreement for such Enhancements, then you hereby grant the following license: a non-exclusive, royalty-free perpetual license to install, use, modify, prepare derivative works, incorporate into other computer software, distribute, and sublicense such enhancements or derivative works thereof, in binary and source code form. COPYRIGHT ========= "pynwb" Copyright (c) 2017-2023, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. If you have questions about your rights to use or distribute this software, please contact Berkeley Lab's Innovation & Partnerships Office at IPO@lbl.gov. NOTICE. This Software was developed under funding from the U.S. Department of Energy and the U.S. Government consequently retains certain rights. As such, the U.S. Government has been granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software to reproduce, distribute copies to the public, prepare derivative works, and perform publicly and display publicly, and to permit other to do so. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/environment-ros3.yml0000644000175100001730000000066214467767506016263 0ustar00runnerdocker# pinned dependencies to reproduce an entire development environment to use PyNWB with ROS3 support name: ros3 channels: - conda-forge - defaults dependencies: - python==3.11 - h5py==3.8.0 - hdmf==3.5.4 - matplotlib==3.7.1 - numpy==1.24.2 - pandas==2.0.0 - python-dateutil==2.8.2 - setuptools - dandi==0.55.1 # NOTE: dandi does not support osx-arm64 - fsspec==2023.6.0 - requests==2.28.1 - aiohttp==3.8.3 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/license.txt0000644000175100001730000000455014467767506014473 0ustar00runnerdocker“pynwb” Copyright (c) 2017-2023, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, U.S. Dept. of Energy nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You are under no obligation whatsoever to provide any bug fixes, patches, or upgrades to the features, functionality or performance of the source code ("Enhancements") to anyone; however, if you choose to make your Enhancements available either publicly, or directly to Lawrence Berkeley National Laboratory, without imposing a separate written license agreement for such Enhancements, then you hereby grant the following license: a non-exclusive, royalty-free perpetual license to install, use, modify, prepare derivative works, incorporate into other computer software, distribute, and sublicense such enhancements or derivative works thereof, in binary and source code form. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/requirements-dev.txt0000644000175100001730000000073314467767506016347 0ustar00runnerdocker# pinned dependencies to reproduce an entire development environment to use PyNWB, run PyNWB tests, check code style, # compute coverage, and create test environments. note that depending on the version of python installed, different # versions of requirements may be installed due to package incompatibilities. # black==23.3.0 codespell==2.2.4 coverage==7.2.2 flake8==6.0.0 flake8-debugger==4.1.2 flake8-print==5.0.0 isort==5.12.0 pytest==7.1.2 pytest-cov==4.0.0 tox==4.4.8 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/requirements-doc.txt0000644000175100001730000000145114467767506016334 0ustar00runnerdocker# dependencies to generate the documentation for PyNWB and test run the sphinx gallery examples that do not require # ROS3 support in h5py. For those examples, use the conda env specified in environment-ros3.yml sphinx>=4 # improved support for docutils>=0.17 sphinx_rtd_theme>=1 # <1 does not work with docutils>=0.17 matplotlib sphinx-gallery # allensdk>=2.13.2 # allensdk reinstalls pynwb and hdmf. TODO set up a separate workflow to test allensdk # MarkupSafe==2.0.1 # resolve incompatibility between jinja2 and markupsafe: https://github.com/AllenInstitute/AllenSDK/issues/2308 Pillow sphinx-copybutton dataframe_image # used to render large dataframe as image in the sphinx gallery to improve html display lxml # used by dataframe_image when using the matplotlib backend hdf5plugin dandi>=0.46.6 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/requirements-min.txt0000644000175100001730000000033314467767506016350 0ustar00runnerdocker# minimum versions of package dependencies for installing PyNWB h5py==2.10 # support for selection of datasets with list of indices added in 2.10 hdmf==3.9.0 numpy==1.18 pandas==1.1.5 python-dateutil==2.7.3 setuptools ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/requirements.txt0000644000175100001730000000026014467767506015566 0ustar00runnerdocker# pinned dependencies to reproduce an entire development environment to use PyNWB h5py==3.8.0 hdmf==3.9.0 numpy==1.24.2 pandas==2.0.0 python-dateutil==2.8.2 setuptools==65.5.1 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5580275 pynwb-2.5.0/setup.cfg0000644000175100001730000000143414467767767014140 0ustar00runnerdocker[versioneer] VCS = git versionfile_source = src/pynwb/_version.py versionfile_build = pynwb/_version.py tag_prefix = '' [flake8] max-line-length = 120 max-complexity = 17 exclude = .git, .tox, __pycache__, build/, dist/, src/pynwb/nwb-schema/ docs/_build/, docs/source/conf.py docs/source/tutorials/ versioneer.py, src/pynwb/_version.py src/pynwb/_due.py per-file-ignores = docs/gallery/*:E402,E501,T201 docs/source/tutorials/*:E402,T201 src/pynwb/io/__init__.py:F401 src/pynwb/legacy/io/__init__.py:F401 tests/integration/__init__.py:F401 src/pynwb/testing/__init__.py:F401 src/pynwb/validate.py:T201 setup.py:T201 test.py:T201 scripts/*:T201 extend-ignore = E203 [metadata] description_file = README.rst [isort] profile = black [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/setup.py0000755000175100001730000000446114467767506014026 0ustar00runnerdocker# -*- coding: utf-8 -*- import sys from setuptools import setup, find_packages # Some Python installations don't add the current directory to path. if '' not in sys.path: sys.path.insert(0, '') import versioneer with open('README.rst', 'r') as fp: readme = fp.read() pkgs = find_packages('src', exclude=['data']) print('found these packages:', pkgs) schema_dir = 'nwb-schema/core' reqs = [ 'h5py>=2.10', 'hdmf>=3.9.0', 'numpy>=1.16', 'pandas>=1.1.5', 'python-dateutil>=2.7.3', 'setuptools' ] print(reqs) setup_args = { 'name': 'pynwb', 'version': versioneer.get_version(), 'cmdclass': versioneer.get_cmdclass(), 'description': 'Package for working with Neurodata stored in the NWB format', 'long_description': readme, 'long_description_content_type': 'text/x-rst; charset=UTF-8', 'author': 'Andrew Tritt', 'author_email': 'ajtritt@lbl.gov', 'url': 'https://github.com/NeurodataWithoutBorders/pynwb', 'license': "BSD", 'install_requires': reqs, 'packages': pkgs, 'package_dir': {'': 'src'}, 'package_data': {'pynwb': ["%s/*.yaml" % schema_dir, "%s/*.json" % schema_dir]}, 'python_requires': '>=3.8', 'classifiers': [ "Programming Language :: Python", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "License :: OSI Approved :: BSD License", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Intended Audience :: Science/Research", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS", "Operating System :: Unix", "Topic :: Scientific/Engineering :: Medical Science Apps." ], 'keywords': 'Neuroscience ' 'python ' 'HDF ' 'HDF5 ' 'cross-platform ' 'open-data ' 'data-format ' 'open-source ' 'open-science ' 'reproducible-research ' 'PyNWB ' 'NWB ' 'NWB:N ' 'NeurodataWithoutBorders', 'zip_safe': False } if __name__ == '__main__': setup(**setup_args) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5340273 pynwb-2.5.0/src/0000755000175100001730000000000014467767767013104 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5580275 pynwb-2.5.0/src/pynwb/0000755000175100001730000000000014467767767014243 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/__init__.py0000644000175100001730000004241014467767506016344 0ustar00runnerdocker'''This package will contain functions, classes, and objects for reading and writing data in NWB format ''' import os.path from pathlib import Path from copy import deepcopy from warnings import warn import h5py from hdmf.spec import NamespaceCatalog from hdmf.utils import docval, getargs, popargs, get_docval from hdmf.backends.io import HDMFIO from hdmf.backends.hdf5 import HDF5IO as _HDF5IO from hdmf.build import BuildManager, TypeMap import hdmf.common CORE_NAMESPACE = 'core' from .spec import NWBDatasetSpec, NWBGroupSpec, NWBNamespace # noqa E402 from .validate import validate # noqa: F401, E402 def __get_resources(): try: from importlib.resources import files except ImportError: # TODO: Remove when python 3.9 becomes the new minimum from importlib_resources import files __location_of_this_file = files(__name__) __core_ns_file_name = 'nwb.namespace.yaml' __schema_dir = 'nwb-schema/core' ret = dict() ret['namespace_path'] = str(__location_of_this_file / __schema_dir / __core_ns_file_name) return ret def _get_resources(): # LEGACY: Needed to support legacy implementation. return __get_resources() # a global namespace catalog global __NS_CATALOG global __TYPE_MAP __NS_CATALOG = NamespaceCatalog(NWBGroupSpec, NWBDatasetSpec, NWBNamespace) hdmf_typemap = hdmf.common.get_type_map() __TYPE_MAP = TypeMap(__NS_CATALOG) __TYPE_MAP.merge(hdmf_typemap, ns_catalog=True) @docval({'name': 'extensions', 'type': (str, TypeMap, list), 'doc': 'a path to a namespace, a TypeMap, or a list consisting of paths to namespaces and TypeMaps', 'default': None}, returns="TypeMap loaded for the given extension or NWB core namespace", rtype=tuple, is_method=False) def get_type_map(**kwargs): ''' Get the TypeMap for the given extensions. If no extensions are provided, return the TypeMap for the core namespace ''' extensions = getargs('extensions', kwargs) type_map = None if extensions is None: type_map = deepcopy(__TYPE_MAP) else: if isinstance(extensions, TypeMap): type_map = extensions else: type_map = deepcopy(__TYPE_MAP) if isinstance(extensions, list): for ext in extensions: if isinstance(ext, str): type_map.load_namespaces(ext) elif isinstance(ext, TypeMap): type_map.merge(ext) else: raise ValueError('extensions must be a list of paths to namespace specs or a TypeMaps') elif isinstance(extensions, str): type_map.load_namespaces(extensions) elif isinstance(extensions, TypeMap): type_map.merge(extensions) return type_map @docval(*get_docval(get_type_map), returns="the namespaces loaded from the given file", rtype=tuple, is_method=False) def get_manager(**kwargs): ''' Get a BuildManager to use for I/O using the given extensions. If no extensions are provided, return a BuildManager that uses the core namespace ''' type_map = get_type_map(**kwargs) return BuildManager(type_map) @docval({'name': 'namespace_path', 'type': str, 'doc': 'the path to the YAML with the namespace definition'}, returns="the namespaces loaded from the given file", rtype=tuple, is_method=False) def load_namespaces(**kwargs): ''' Load namespaces from file ''' namespace_path = getargs('namespace_path', kwargs) return __TYPE_MAP.load_namespaces(namespace_path) # load the core namespace, i.e. base NWB specification __resources = __get_resources() if os.path.exists(__resources['namespace_path']): load_namespaces(__resources['namespace_path']) else: raise RuntimeError( "'core' is not a registered namespace. If you installed PyNWB locally using a git clone, you need to " "use the --recurse_submodules flag when cloning. See developer installation instructions here: " "https://pynwb.readthedocs.io/en/stable/install_developers.html#install-from-git-repository" ) def available_namespaces(): """Returns all namespaces registered in the namespace catalog""" return __NS_CATALOG.namespaces # a function to register a container classes with the global map @docval({'name': 'neurodata_type', 'type': str, 'doc': 'the neurodata_type to get the spec for'}, {'name': 'namespace', 'type': str, 'doc': 'the name of the namespace'}, {"name": "container_cls", "type": type, "doc": "the class to map to the specified neurodata_type", 'default': None}, is_method=False) def register_class(**kwargs): """Register an NWBContainer class to use for reading and writing a neurodata_type from a specification If container_cls is not specified, returns a decorator for registering an NWBContainer subclass as the class for neurodata_type in namespace. """ neurodata_type, namespace, container_cls = getargs('neurodata_type', 'namespace', 'container_cls', kwargs) def _dec(cls): __TYPE_MAP.register_container_type(namespace, neurodata_type, cls) return cls if container_cls is None: return _dec else: _dec(container_cls) # a function to register an object mapper for a container class @docval({"name": "container_cls", "type": type, "doc": "the Container class for which the given ObjectMapper class gets used"}, {"name": "mapper_cls", "type": type, "doc": "the ObjectMapper class to use to map", 'default': None}, is_method=False) def register_map(**kwargs): """Register an ObjectMapper to use for a Container class type If mapper_cls is not specified, returns a decorator for registering an ObjectMapper class as the mapper for container_cls. If mapper_cls is specified, register the class as the mapper for container_cls """ container_cls, mapper_cls = getargs('container_cls', 'mapper_cls', kwargs) def _dec(cls): __TYPE_MAP.register_map(container_cls, cls) return cls if mapper_cls is None: return _dec else: _dec(mapper_cls) @docval({'name': 'neurodata_type', 'type': str, 'doc': 'the neurodata_type to get the NWBContainer class for'}, {'name': 'namespace', 'type': str, 'doc': 'the namespace the neurodata_type is defined in'}, is_method=False) def get_class(**kwargs): """ Parse the YAML file for a given neurodata_type that is a subclass of NWBContainer and automatically generate its python API. This will work for most containers, but is known to not work for descendants of MultiContainerInterface and DynamicTable, so these must be defined manually (for now). `get_class` infers the API mapping directly from the specification. If you want to define a custom mapping, you should not use this function and you should define the class manually. Examples: Generating and registering an extension is as simple as:: MyClass = get_class('MyClass', 'ndx-my-extension') `get_class` defines only the `__init__` for the class. In cases where you want to provide additional methods for querying, plotting, etc. you can still use `get_class` and attach methods to the class after-the-fact, e.g.:: def get_sum(self, a, b): return self.feat1 + self.feat2 MyClass.get_sum = get_sum """ neurodata_type, namespace = getargs('neurodata_type', 'namespace', kwargs) return __TYPE_MAP.get_dt_container_cls(neurodata_type, namespace) class NWBHDF5IO(_HDF5IO): @docval({'name': 'path', 'type': (str, Path), 'doc': 'the path to the HDF5 file', 'default': None}, {'name': 'mode', 'type': str, 'doc': 'the mode to open the HDF5 file with, one of ("w", "r", "r+", "a", "w-", "x")', 'default': 'r'}, {'name': 'load_namespaces', 'type': bool, 'doc': 'whether or not to load cached namespaces from given path - not applicable in write mode', 'default': False}, {'name': 'manager', 'type': BuildManager, 'doc': 'the BuildManager to use for I/O', 'default': None}, {'name': 'extensions', 'type': (str, TypeMap, list), 'doc': 'a path to a namespace, a TypeMap, or a list consisting paths to namespaces and TypeMaps', 'default': None}, {'name': 'file', 'type': [h5py.File, 'S3File'], 'doc': 'a pre-existing h5py.File object', 'default': None}, {'name': 'comm', 'type': "Intracomm", 'doc': 'the MPI communicator to use for parallel I/O', 'default': None}, {'name': 'driver', 'type': str, 'doc': 'driver for h5py to use when opening HDF5 file', 'default': None}, {'name': 'herd_path', 'type': str, 'doc': 'The path to the HERD', 'default': None},) def __init__(self, **kwargs): path, mode, manager, extensions, load_namespaces, file_obj, comm, driver, herd_path =\ popargs('path', 'mode', 'manager', 'extensions', 'load_namespaces', 'file', 'comm', 'driver', 'herd_path', kwargs) # Define the BuildManager to use if load_namespaces: if manager is not None: warn("loading namespaces from file - ignoring 'manager'") if extensions is not None: warn("loading namespaces from file - ignoring 'extensions' argument") # namespaces are not loaded when creating an NWBHDF5IO object in write mode if 'w' in mode or mode == 'x': raise ValueError("cannot load namespaces from file when writing to it") tm = get_type_map() super().load_namespaces(tm, path, file=file_obj, driver=driver) manager = BuildManager(tm) # XXX: Leaving this here in case we want to revert to this strategy for # loading cached namespaces # ns_catalog = NamespaceCatalog(NWBGroupSpec, NWBDatasetSpec, NWBNamespace) # super().load_namespaces(ns_catalog, path) # tm = TypeMap(ns_catalog) # tm.copy_mappers(get_type_map()) else: if manager is not None and extensions is not None: raise ValueError("'manager' and 'extensions' cannot be specified together") elif extensions is not None: manager = get_manager(extensions=extensions) elif manager is None: manager = get_manager() # Open the file super().__init__(path, manager=manager, mode=mode, file=file_obj, comm=comm, driver=driver, herd_path=herd_path) @property def nwb_version(self): """ Get the version of the NWB file opened via this NWBHDF5IO object. :returns: Tuple consisting of: 1) the original version string as stored in the file and 2) a tuple with the parsed components of the version string, consisting of integers and strings, e.g., (2, 5, 1, beta). (None, None) will be returned if the nwb_version is missing, e.g., in the case when no data has been written to the file yet. """ # Get the version string for the NWB file try: nwb_version_string = self._file.attrs['nwb_version'] # KeyError occurs when the file is empty (e.g., when creating a new file nothing has been written) # or when the HDF5 file is not a valid NWB file except KeyError: return None, None # Other system may have written nwb_version as a fixed-length string, resulting in a numpy.bytes_ object # on read, rather than a variable-length string. To address this, decode the bytes if necessary. if not isinstance(nwb_version_string, str): nwb_version_string = nwb_version_string.decode() # Parse the version string nwb_version_parts = nwb_version_string.replace("-", ".").replace("_", ".").split(".") nwb_version = tuple([int(i) if i.isnumeric() else i for i in nwb_version_parts]) return nwb_version_string, nwb_version @docval(*get_docval(_HDF5IO.read), {'name': 'skip_version_check', 'type': bool, 'doc': 'skip checking of NWB version', 'default': False}) def read(self, **kwargs): """ Read the NWB file from the IO source. :raises TypeError: If the NWB file version is missing or not supported :return: NWBFile container """ # Check that the NWB file is supported skip_verison_check = popargs('skip_version_check', kwargs) if not skip_verison_check: file_version_str, file_version = self.nwb_version if file_version is None: raise TypeError("Missing NWB version in file. The file is not a valid NWB file.") if file_version[0] < 2: raise TypeError("NWB version %s not supported. PyNWB supports NWB files version 2 and above." % str(file_version_str)) # read the file file = super().read(**kwargs) return file @docval({'name': 'src_io', 'type': HDMFIO, 'doc': 'the HDMFIO object (such as NWBHDF5IO) that was used to read the data to export'}, {'name': 'nwbfile', 'type': 'NWBFile', 'doc': 'the NWBFile object to export. If None, then the entire contents of src_io will be exported', 'default': None}, {'name': 'write_args', 'type': dict, 'doc': 'arguments to pass to :py:meth:`write_builder`', 'default': None}) def export(self, **kwargs): """ Export an NWB file to a new NWB file using the HDF5 backend. If ``nwbfile`` is provided, then the build manager of ``src_io`` is used to build the container, and the resulting builder will be exported to the new backend. So if ``nwbfile`` is provided, ``src_io`` must have a non-None manager property. If ``nwbfile`` is None, then the contents of ``src_io`` will be read and exported to the new backend. Arguments can be passed in for the ``write_builder`` method using ``write_args``. Some arguments may not be supported during export. ``{'link_data': False}`` can be used to copy any datasets linked to from the original file instead of creating a new link to those datasets in the exported file. The exported file will not contain any links to the original file. All links, internal and external, will be preserved in the exported file. All references will also be preserved in the exported file. The exported file will use the latest schema version supported by the version of PyNWB used. For example, if the input file uses the NWB schema version 2.1 and the latest schema version supported by PyNWB is 2.3, then the exported file will use the 2.3 NWB schema. Example usage: .. code-block:: python with NWBHDF5IO(self.read_path, mode='r') as read_io: nwbfile = read_io.read() # ... # modify nwbfile nwbfile.set_modified() # this may be necessary if the modifications are changes to attributes with NWBHDF5IO(self.export_path, mode='w') as export_io: export_io.export(src_io=read_io, nwbfile=nwbfile) See :ref:`export` and :ref:`modifying_data` for more information and examples. """ nwbfile = popargs('nwbfile', kwargs) kwargs['container'] = nwbfile super().export(**kwargs) from . import io as __io # noqa: F401,E402 from .core import NWBContainer, NWBData # noqa: F401,E402 from .base import TimeSeries, ProcessingModule # noqa: F401,E402 from .file import NWBFile # noqa: F401,E402 from . import behavior # noqa: F401,E402 from . import device # noqa: F401,E402 from . import ecephys # noqa: F401,E402 from . import epoch # noqa: F401,E402 from . import icephys # noqa: F401,E402 from . import image # noqa: F401,E402 from . import misc # noqa: F401,E402 from . import ogen # noqa: F401,E402 from . import ophys # noqa: F401,E402 from . import retinotopy # noqa: F401,E402 from . import legacy # noqa: F401,E402 from hdmf.data_utils import DataChunkIterator # noqa: F401,E402 from hdmf.backends.hdf5 import H5DataIO # noqa: F401,E402 from . import _version # noqa: F401,E402 __version__ = _version.get_versions()['version'] from ._due import due, BibTeX # noqa: E402 due.cite( BibTeX(""" @article {10.7554/eLife.78362, article_type = {journal}, title = {{The Neurodata Without Borders ecosystem for neurophysiological data science}}, author = {R\"ubel, Oliver and Tritt, Andrew and Ly, Ryan and Dichter, Benjamin K and Ghosh, Satrajit and Niu, Lawrence and Baker, Pamela and Soltesz, Ivan and Ng, Lydia and Svoboda, Karel and Frank, Loren and Bouchard, Kristofer E}, editor = {Colgin, Laura L and Jadhav, Shantanu P}, volume = {11}, year = {2022}, month = {oct}, pub_date = {2022-10-04}, pages = {e78362}, citation = {eLife 2022;11:e78362}, doi = {10.7554/eLife.78362}, url = {https://doi.org/10.7554/eLife.78362}, keywords = {Neurophysiology, data ecosystem, data language, data standard, FAIR data, archive}, journal = {eLife}, issn = {2050-084X}, publisher = {eLife Sciences Publications, Ltd}} """), description="The Neurodata Without Borders ecosystem for neurophysiological data science", path="pynwb/", version=__version__, cite_module=True ) del due, BibTeX ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/_due.py0000644000175100001730000000374214467767506015526 0ustar00runnerdocker# emacs: at the end of the file # ex: set sts=4 ts=4 sw=4 et: # ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### # """ Stub file for a guaranteed safe import of duecredit constructs: if duecredit is not available. To use it, place it into your project codebase to be imported, e.g. copy as cp stub.py /path/tomodule/module/due.py Note that it might be better to avoid naming it duecredit.py to avoid shadowing installed duecredit. Then use in your code as from .due import due, Doi, BibTeX, Text See https://github.com/duecredit/duecredit/blob/master/README.md for examples. Origin: Originally a part of the duecredit Copyright: 2015-2019 DueCredit developers License: BSD-2 """ __version__ = '0.0.8' class InactiveDueCreditCollector(object): """Just a stub at the Collector which would not do anything""" def _donothing(self, *args, **kwargs): """Perform no good and no bad""" pass def dcite(self, *args, **kwargs): """If I could cite I would""" def nondecorating_decorator(func): return func return nondecorating_decorator active = False activate = add = cite = dump = load = _donothing def __repr__(self): return self.__class__.__name__ + '()' def _donothing_func(*args, **kwargs): """Perform no good and no bad""" pass try: from duecredit import due, BibTeX, Doi, Url, Text if 'due' in locals() and not hasattr(due, 'cite'): raise RuntimeError( "Imported due lacks .cite. DueCredit is now disabled") except Exception as e: if not isinstance(e, ImportError): import logging logging.getLogger("duecredit").error( "Failed to import duecredit due to %s" % str(e)) # Initiate due stub due = InactiveDueCreditCollector() BibTeX = Doi = Url = Text = _donothing_func # Emacs mode definitions # Local Variables: # mode: python # py-indent-offset: 4 # tab-width: 4 # indent-tabs-mode: nil # End: ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5580275 pynwb-2.5.0/src/pynwb/_version.py0000644000175100001730000000076114467767767016445 0ustar00runnerdocker # This file was generated by 'versioneer.py' (0.26) from # revision-control system data, or from the parent directory name of an # unpacked source archive. Distribution tarballs contain a pre-generated copy # of this file. import json version_json = ''' { "date": "2023-08-18T15:20:11-0700", "dirty": false, "error": null, "full-revisionid": "68c4f5645d00f3958471e5e2bc360c90f49a4740", "version": "2.5.0" } ''' # END VERSION_JSON def get_versions(): return json.loads(version_json) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/base.py0000644000175100001730000007010014467767506015514 0ustar00runnerdockerfrom warnings import warn from collections.abc import Iterable from typing import NamedTuple import numpy as np from hdmf.utils import docval, popargs_to_dict, get_docval, popargs from hdmf.common import DynamicTable, VectorData from hdmf.utils import get_data_shape from . import register_class, CORE_NAMESPACE from .core import NWBDataInterface, MultiContainerInterface, NWBData @register_class('ProcessingModule', CORE_NAMESPACE) class ProcessingModule(MultiContainerInterface): """ Processing module. This is a container for one or more containers that provide data at intermediate levels of analysis ProcessingModules should be created through calls to NWB.create_module(). They should not be instantiated directly """ __nwbfields__ = ('description',) __clsconf__ = { 'attr': 'data_interfaces', 'add': 'add', 'type': (NWBDataInterface, DynamicTable), 'get': 'get' } @docval({'name': 'name', 'type': str, 'doc': 'The name of this processing module'}, {'name': 'description', 'type': str, 'doc': 'Description of this processing module'}, {'name': 'data_interfaces', 'type': (list, tuple, dict), 'doc': 'NWBDataInterfaces that belong to this ProcessingModule', 'default': None}) def __init__(self, **kwargs): description, data_interfaces = popargs("description", "data_interfaces", kwargs) super().__init__(**kwargs) self.description = description self.data_interfaces = data_interfaces @property def containers(self): return self.data_interfaces @docval({'name': 'container', 'type': (NWBDataInterface, DynamicTable), 'doc': 'the NWBDataInterface to add to this Module'}) def add_container(self, **kwargs): ''' Add an NWBContainer to this ProcessingModule ''' warn(PendingDeprecationWarning('add_container will be replaced by add')) self.add(kwargs['container']) @docval({'name': 'container_name', 'type': str, 'doc': 'the name of the NWBContainer to retrieve'}) def get_container(self, **kwargs): ''' Retrieve an NWBContainer from this ProcessingModule ''' warn(PendingDeprecationWarning('get_container will be replaced by get')) return self.get(kwargs['container_name']) @docval({'name': 'NWBDataInterface', 'type': (NWBDataInterface, DynamicTable), 'doc': 'the NWBDataInterface to add to this Module'}) def add_data_interface(self, **kwargs): warn(PendingDeprecationWarning('add_data_interface will be replaced by add')) self.add(kwargs['NWBDataInterface']) @docval({'name': 'data_interface_name', 'type': str, 'doc': 'the name of the NWBContainer to retrieve'}) def get_data_interface(self, **kwargs): warn(PendingDeprecationWarning('get_data_interface will be replaced by get')) return self.get(kwargs['data_interface_name']) @register_class('TimeSeries', CORE_NAMESPACE) class TimeSeries(NWBDataInterface): """A generic base class for time series data""" __nwbfields__ = ("comments", "description", "data", "resolution", "conversion", "offset", "unit", "timestamps", "timestamps_unit", "interval", "starting_time", "rate", "starting_time_unit", "control", "control_description", "continuity") __time_unit = "seconds" # values used when a TimeSeries is read and missing required fields DEFAULT_DATA = np.ndarray(shape=(0, ), dtype=np.uint8) DEFAULT_UNIT = 'unknown' DEFAULT_RESOLUTION = -1.0 DEFAULT_CONVERSION = 1.0 DEFAULT_OFFSET = 0.0 @docval({'name': 'name', 'type': str, 'doc': 'The name of this TimeSeries dataset'}, # required {'name': 'data', 'type': ('array_data', 'data', 'TimeSeries'), 'doc': ('The data values. The first dimension must be time. ' 'Can also store binary data, e.g., image frames')}, {'name': 'unit', 'type': str, 'doc': 'The base unit of measurement (should be SI unit)'}, {'name': 'resolution', 'type': float, 'doc': 'The smallest meaningful difference (in specified unit) between values in data', 'default': DEFAULT_RESOLUTION}, {'name': 'conversion', 'type': float, 'doc': 'Scalar to multiply each element in data to convert it to the specified unit', 'default': DEFAULT_CONVERSION}, { 'name': 'offset', 'type': float, 'doc': ( "Scalar to add to each element in the data scaled by 'conversion' to finish converting it to the " "specified unit." ), 'default': DEFAULT_OFFSET }, {'name': 'timestamps', 'type': ('array_data', 'data', 'TimeSeries'), 'shape': (None,), 'doc': 'Timestamps for samples stored in data', 'default': None}, {'name': 'starting_time', 'type': float, 'doc': 'The timestamp of the first sample', 'default': None}, {'name': 'rate', 'type': float, 'doc': 'Sampling rate in Hz', 'default': None}, {'name': 'comments', 'type': str, 'doc': 'Human-readable comments about this TimeSeries dataset', 'default': 'no comments'}, {'name': 'description', 'type': str, 'doc': 'Description of this TimeSeries dataset', 'default': 'no description'}, {'name': 'control', 'type': Iterable, 'doc': 'Numerical labels that apply to each element in data', 'default': None}, {'name': 'control_description', 'type': Iterable, 'doc': 'Description of each control value', 'default': None}, {'name': 'continuity', 'type': str, 'default': None, 'enum': ["continuous", "instantaneous", "step"], 'doc': 'Optionally describe the continuity of the data. Can be "continuous", "instantaneous", or' '"step". For example, a voltage trace would be "continuous", because samples are recorded from a ' 'continuous process. An array of lick times would be "instantaneous", because the data represents ' 'distinct moments in time. Times of image presentations would be "step" because the picture ' 'remains the same until the next time-point. This field is optional, but is useful in providing ' 'information about the underlying data. It may inform the way this data is interpreted, the way it ' 'is visualized, and what analysis methods are applicable.'}) def __init__(self, **kwargs): """Create a TimeSeries object """ keys_to_set = ("starting_time", "rate", "resolution", "comments", "description", "conversion", "offset", "unit", "control", "control_description", "continuity") args_to_set = popargs_to_dict(keys_to_set, kwargs) keys_to_process = ("data", "timestamps") # these are properties and cannot be set with setattr args_to_process = popargs_to_dict(keys_to_process, kwargs) super().__init__(**kwargs) for key, val in args_to_set.items(): setattr(self, key, val) data = args_to_process['data'] self.fields['data'] = data if isinstance(data, TimeSeries): data.__add_link('data_link', self) timestamps = args_to_process['timestamps'] if timestamps is not None: if self.rate is not None: raise ValueError('Specifying rate and timestamps is not supported.') if self.starting_time is not None: raise ValueError('Specifying starting_time and timestamps is not supported.') self.fields['timestamps'] = timestamps self.timestamps_unit = self.__time_unit self.interval = 1 if isinstance(timestamps, TimeSeries): timestamps.__add_link('timestamp_link', self) elif self.rate is not None: if self.starting_time is None: # override default if rate is provided but not starting time self.starting_time = 0.0 self.starting_time_unit = self.__time_unit else: raise TypeError("either 'timestamps' or 'rate' must be specified") if not self._check_time_series_dimension(): warn("%s '%s': Length of data does not match length of timestamps. Your data may be transposed. " "Time should be on the 0th dimension" % (self.__class__.__name__, self.name)) def _check_time_series_dimension(self): """Check that the 0th dimension of data equals the length of timestamps, when applicable. """ if self.timestamps is None: return True data_shape = get_data_shape(data=self.fields["data"], strict_no_data_load=True) timestamps_shape = get_data_shape(data=self.fields["timestamps"], strict_no_data_load=True) # skip check if shape of data or timestamps cannot be computed if data_shape is None or timestamps_shape is None: return True # skip check if length of the first dimension is not known if data_shape[0] is None or timestamps_shape[0] is None: return True return data_shape[0] == timestamps_shape[0] @property def num_samples(self): ''' Tries to return the number of data samples. If this cannot be assessed, returns None. ''' def unreadable_warning(attr): return ( 'The {} attribute on this TimeSeries (named: {}) has a __len__, ' 'but it cannot be read'.format(attr, self.name) ) def no_len_warning(attr): return 'The {} attribute on this TimeSeries (named: {}) has no __len__'.format(attr, self.name) if hasattr(self.data, '__len__'): try: return len(self.data) # for an ndarray this will return the first element of shape except TypeError: warn(unreadable_warning('data'), UserWarning) else: warn(no_len_warning('data'), UserWarning) # only get here if self.data has no __len__ or __len__ is unreadable if hasattr(self.timestamps, '__len__'): try: return len(self.timestamps) except TypeError: warn(unreadable_warning('timestamps'), UserWarning) elif self.rate is None and self.starting_time is None: warn(no_len_warning('timestamps'), UserWarning) return None @property def data(self): if isinstance(self.fields['data'], TimeSeries): return self.fields['data'].data else: return self.fields['data'] @property def data_link(self): return self.__get_links('data_link') @property def timestamps(self): if 'timestamps' not in self.fields: return None if isinstance(self.fields['timestamps'], TimeSeries): return self.fields['timestamps'].timestamps else: return self.fields['timestamps'] @property def timestamp_link(self): return self.__get_links('timestamp_link') def __get_links(self, links): ret = self.fields.get(links, list()) ret = set(ret) return ret def __add_link(self, links_key, link): self.fields.setdefault(links_key, list()).append(link) @property def time_unit(self): return self.__time_unit def get_timestamps(self): if self.fields.get('timestamps'): return self.timestamps else: return np.arange(len(self.data)) / self.rate + self.starting_time def get_data_in_units(self): return np.asarray(self.data) * self.conversion + self.offset @register_class('Image', CORE_NAMESPACE) class Image(NWBData): """ Abstract image class. It is recommended to instead use pynwb.image.GrayscaleImage or pynwb.image.RGPImage where appropriate. """ __nwbfields__ = ('data', 'resolution', 'description') @docval({'name': 'name', 'type': str, 'doc': 'The name of this image'}, {'name': 'data', 'type': ('array_data', 'data'), 'doc': 'data of image. Dimensions: x, y [, r,g,b[,a]]', 'shape': ((None, None), (None, None, 3), (None, None, 4))}, {'name': 'resolution', 'type': float, 'doc': 'pixels / cm', 'default': None}, {'name': 'description', 'type': str, 'doc': 'description of image', 'default': None}) def __init__(self, **kwargs): args_to_set = popargs_to_dict(("resolution", "description"), kwargs) super().__init__(**kwargs) for key, val in args_to_set.items(): setattr(self, key, val) @register_class('ImageReferences', CORE_NAMESPACE) class ImageReferences(NWBData): """ Ordered dataset of references to Image objects. """ __nwbfields__ = ('data', ) @docval({'name': 'name', 'type': str, 'doc': 'The name of this ImageReferences object.'}, {'name': 'data', 'type': 'array_data', 'doc': 'The images in order.'},) def __init__(self, **kwargs): # NOTE we do not use the docval shape validator here because it will recognize a list of P MxN images as # having shape (P, M, N) # check type and dimensionality for image in kwargs['data']: assert isinstance(image, Image), "Images used in ImageReferences must have type Image, not %s" % type(image) super().__init__(**kwargs) @register_class('Images', CORE_NAMESPACE) class Images(MultiContainerInterface): """An collection of images with an optional way to specify the order of the images using the "order_of_images" dataset. An order must be specified if the images are referenced by index, e.g., from an IndexSeries. """ __nwbfields__ = ('description', {'name': 'order_of_images', 'child': True, 'required_name': 'order_of_images'}) __clsconf__ = { 'attr': 'images', 'add': 'add_image', 'type': Image, 'get': 'get_image', 'create': 'create_image' } @docval({'name': 'name', 'type': str, 'doc': 'The name of this set of images'}, {'name': 'images', 'type': 'array_data', 'doc': 'image objects', 'default': None}, {'name': 'description', 'type': str, 'doc': 'description of images', 'default': 'no description'}, {'name': 'order_of_images', 'type': ImageReferences, 'doc': 'Ordered dataset of references to Image objects stored in the parent group.', 'default': None},) def __init__(self, **kwargs): args_to_set = popargs_to_dict(("description", "images", "order_of_images"), kwargs) super().__init__(**kwargs) for key, val in args_to_set.items(): setattr(self, key, val) class TimeSeriesReference(NamedTuple): """ Class used to represent data values of a :py:class:`~pynwb.base.TimeSeriesReferenceVectorData` This is a ``typing.NamedTuple`` type with predefined tuple components :py:meth:`~pynwb.base.TimeSeriesReference.idx_start`, :py:meth:`~pynwb.base.TimeSeriesReference.count`, and :py:meth:`~pynwb.base.TimeSeriesReference.timeseries`. :cvar idx_start: :cvar count: :cvar timeseries: """ idx_start: int """Start index in time for the timeseries""" count: int """Number of timesteps to be selected starting from :py:meth:`~pynwb.base.TimeSeriesReference.idx_start`""" timeseries: TimeSeries """The :py:class:`~pynwb.base.TimeSeries` object the TimeSeriesReference applies to""" def check_types(self): """ Helper function to check correct types for :py:meth:`~pynwb.base.TimeSeriesReference.idx_start`, :py:meth:`~pynwb.base.TimeSeriesReference.count`, and :py:meth:`~pynwb.base.TimeSeriesReference.timeseries`. This function is usually used in the try/except block to check for `TypeError` raised by the function. See also :py:meth:`~pynwb.base.TimeSeriesReference.isvalid` to check both validity of types and the reference itself. :returns: True if successful. If unsuccessful `TypeError` is raised. :raises TypeError: If one of the fields does not match the expected type """ if not isinstance(self.idx_start, (int, np.integer)): raise TypeError("idx_start must be an integer not %s" % str(type(self.idx_start))) if not isinstance(self.count, (int, np.integer)): raise TypeError("count must be an integer %s" % str(type(self.count))) if not isinstance(self.timeseries, TimeSeries): raise TypeError("timeseries must be of type TimeSeries. %s" % str(type(self.timeseries))) return True def isvalid(self): """ Check whether the reference is valid. Setting :py:meth:`~pynwb.base.TimeSeriesReference.idx_start` and :py:meth:`~pynwb.base.TimeSeriesReference.count` to -1 is used to indicate invalid references. This is useful to allow for missing data in :py:class:`~pynwb.base.TimeSeriesReferenceVectorData` :returns: True if the selection is valid. Returns False if both :py:meth:`~pynwb.base.TimeSeriesReference.idx_start` and :py:meth:`~pynwb.base.TimeSeriesReference.count` are negative. Raises `IndexError` in case the indices are bad. :raises IndexError: If the combination of :py:meth:`~pynwb.base.TimeSeriesReference.idx_start` and :py:meth:`~pynwb.base.TimeSeriesReference.count` are not valid for the given timeseries. :raises TypeError: If one of the fields does not match the expected type """ # Check types first self.check_types() # Check for none-type selection if self.idx_start < 0 and self.count < 0: return False num_samples = self.timeseries.num_samples if num_samples is not None: if self.idx_start >= num_samples or self.idx_start < 0: raise IndexError("'idx_start' %i out of range for timeseries '%s'" % (self.idx_start, self.timeseries.name)) if self.count < 0: raise IndexError("'count' %i invalid. 'count' must be positive" % self.count) if (self.idx_start + self.count) > num_samples: raise IndexError("'idx_start + count' out of range for timeseries '%s'" % self.timeseries.name) return True @property def timestamps(self): """ Get the floating point timestamp offsets in seconds from the timeseries that correspond to the array. These are either loaded directly from the :py:meth:`~pynwb.base.TimeSeriesReference.timeseries` timestamps or calculated from the starting time and sampling rate. :raises IndexError: If the combination of :py:meth:`~pynwb.base.TimeSeriesReference.idx_start` and :py:meth:`~pynwb.base.TimeSeriesReference.count` are not valid for the given timeseries. :raises TypeError: If one of the fields does not match the expected type :returns: Array with the timestamps. """ # isvalid will be False only if both idx_start and count are negative. Otherwise well get errors or be True. if not self.isvalid(): return None # load the data from the timestamps elif self.timeseries.timestamps is not None: return self.timeseries.timestamps[self.idx_start: (self.idx_start + self.count)] # construct the timestamps from the starting_time and rate else: start_time = self.timeseries.rate * self.idx_start + self.timeseries.starting_time return np.arange(0, self.count) * self.timeseries.rate + start_time @property def data(self): """ Get the selected data values. This is a convenience function to slice data from the :py:meth:`~pynwb.base.TimeSeriesReference.timeseries` based on the given :py:meth:`~pynwb.base.TimeSeriesReference.idx_start` and :py:meth:`~pynwb.base.TimeSeriesReference.count` :raises IndexError: If the combination of :py:meth:`~pynwb.base.TimeSeriesReference.idx_start` and :py:meth:`~pynwb.base.TimeSeriesReference.count` are not valid for the given timeseries. :raises TypeError: If one of the fields does not match the expected type :returns: Result of ``self.timeseries.data[self.idx_start: (self.idx_start + self.count)]``. Returns None in case the reference is invalid (i.e., if both :py:meth:`~pynwb.base.TimeSeriesReference.idx_start` and :py:meth:`~pynwb.base.TimeSeriesReference.count` are negative. """ # isvalid will be False only if both idx_start and count are negative. Otherwise well get errors or be True. if not self.isvalid(): return None # load the data from the timeseries return self.timeseries.data[self.idx_start: (self.idx_start + self.count)] @register_class('TimeSeriesReferenceVectorData', CORE_NAMESPACE) class TimeSeriesReferenceVectorData(VectorData): """ Column storing references to a TimeSeries (rows). For each TimeSeries this VectorData column stores the start_index and count to indicate the range in time to be selected as well as an object reference to the TimeSeries. **Representing missing values** In practice we sometimes need to be able to represent missing values, e.g., in the :py:class:`~pynwb.icephys.IntracellularRecordingsTable` we have :py:class:`~pynwb.base.TimeSeriesReferenceVectorData` to link to stimulus and response recordings, but a user can specify either only one of them or both. Since there is no ``None`` value for a complex types like ``(idx_start, count, TimeSeries)``, NWB defines ``None`` as ``(-1, -1, TimeSeries)`` for storage, i.e., if the ``idx_start`` (and ``count``) is negative then this indicates an invalid link (in practice both ``idx_start`` and ``count`` must always either both be positive or both be negative). When selecting data via the :py:meth:`~pynwb.base.TimeSeriesReferenceVectorData.get` or :py:meth:`~pynwb.base. TimeSeriesReferenceVectorData.__getitem__` functions, ``(-1, -1, TimeSeries)`` values are replaced by the corresponding :py:class:`~pynwb.base.TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_NONE_TYPE` tuple to avoid exposing NWB storage internals to the user and simplifying the use of and checking for missing values. **NOTE:** We can still inspect the raw data values by looking at ``self.data`` directly instead. :cvar TIME_SERIES_REFERENCE_TUPLE: :cvar TIME_SERIES_REFERENCE_NONE_TYPE: """ TIME_SERIES_REFERENCE_TUPLE = TimeSeriesReference """Return type when calling :py:meth:`~pynwb.base.TimeSeriesReferenceVectorData.get` or :py:meth:`~pynwb.base. TimeSeriesReferenceVectorData.__getitem__`.""" TIME_SERIES_REFERENCE_NONE_TYPE = TIME_SERIES_REFERENCE_TUPLE(None, None, None) """Tuple used to represent None values when calling :py:meth:`~pynwb.base.TimeSeriesReferenceVectorData.get` or :py:meth:`~pynwb.base. TimeSeriesReferenceVectorData.__getitem__`. See also :py:class:`~pynwb.base.TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE`""" @docval({'name': 'name', 'type': str, 'doc': 'the name of this VectorData', 'default': 'timeseries'}, {'name': 'description', 'type': str, 'doc': 'a description for this column', 'default': "Column storing references to a TimeSeries (rows). For each TimeSeries this " "VectorData column stores the start_index and count to indicate the range in time " "to be selected as well as an object reference to the TimeSeries."}, *get_docval(VectorData.__init__, 'data')) def __init__(self, **kwargs): super().__init__(**kwargs) # CAUTION: Define any logic specific for init in the self._init_internal function, not here! self._init_internal() def _init_internal(self): """ Called from __init__ to perform initialization specific to this class. This is done here due to the :py:class:`~pynwb.io.epoch.TimeIntervalsMap` having to migrate legacy VectorData to TimeSeriesReferenceVectorData. In this way, if dedicated logic init logic needs to be added to this class then we have a place for it without having to also update :py:class:`~pynwb.io.epoch.TimeIntervalsMap` (which would likely get forgotten) """ pass @docval({'name': 'val', 'type': (TIME_SERIES_REFERENCE_TUPLE, tuple), 'doc': 'the value to add to this column. If this is a regular tuple then it ' 'must be convertible to a TimeSeriesReference'}) def add_row(self, **kwargs): """Append a data value to this column.""" val = kwargs['val'] if not isinstance(val, self.TIME_SERIES_REFERENCE_TUPLE): val = self.TIME_SERIES_REFERENCE_TUPLE(*val) val.check_types() super().append(val) @docval({'name': 'arg', 'type': (TIME_SERIES_REFERENCE_TUPLE, tuple), 'doc': 'the value to append to this column. If this is a regular tuple then it ' 'must be convertible to a TimeSeriesReference'}) def append(self, **kwargs): """Append a data value to this column.""" arg = kwargs['arg'] if not isinstance(arg, self.TIME_SERIES_REFERENCE_TUPLE): arg = self.TIME_SERIES_REFERENCE_TUPLE(*arg) arg.check_types() super().append(arg) def get(self, key, **kwargs): """ Retrieve elements from this object. The function uses :py:class:`~pynwb.base.TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE` to describe individual records in the dataset. This allows the code to avoid exposing internal details of the schema to the user and simplifies handling of missing values by explicitly representing missing values via :py:class:`~pynwb.base.TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_NONE_TYPE` rather than the internal representation used for storage of ``(-1, -1, TimeSeries)``. :param key: Selection of the elements :param kwargs: Ignored :returns: :py:class:`~pynwb.base.TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE` if a single element is being selected. Otherwise return a list of :py:class:`~pynwb.base.TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE` objects. Missing values are represented by :py:class:`~pynwb.base.TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_NONE_TYPE` in which all values (i.e., idx_start, count, timeseries) are set to None. """ vals = super().get(key) # we only selected one row. if isinstance(key, (int, np.integer)): # NOTE: If we never wrote the data to disk, then vals will be a single tuple. # If the data is loaded from an h5py.Dataset then vals will be a single # np.void object. I.e., an alternative check would be # if isinstance(vals, tuple) or isinstance(vals, np.void): # ... if vals[0] < 0 or vals[1] < 0: return self.TIME_SERIES_REFERENCE_NONE_TYPE else: return self.TIME_SERIES_REFERENCE_TUPLE(*vals) else: # key selected multiple rows # When loading from HDF5 we get an np.ndarray otherwise we get list-of-list. This # makes the values consistent and transforms the data to use our namedtuple type re = [self.TIME_SERIES_REFERENCE_NONE_TYPE if (v[0] < 0 or v[1] < 0) else self.TIME_SERIES_REFERENCE_TUPLE(*v) for v in vals] return re ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/behavior.py0000644000175100001730000001544214467767506016411 0ustar00runnerdockerimport warnings from hdmf.utils import docval, popargs, get_docval, get_data_shape from . import register_class, CORE_NAMESPACE from .core import MultiContainerInterface from .misc import IntervalSeries from .base import TimeSeries @register_class('SpatialSeries', CORE_NAMESPACE) class SpatialSeries(TimeSeries): """ Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, "straight-ahead" might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values. """ __nwbfields__ = ('reference_frame',) @docval(*get_docval(TimeSeries.__init__, 'name'), # required {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': ((None, ), (None, None)), # required 'doc': ('The data values. Can be 1D or 2D. The first dimension must be time. If 2D, there can be 1, 2, ' 'or 3 columns, which represent x, y, and z.')}, {'name': 'reference_frame', 'type': str, # required 'doc': 'description defining what the zero-position is'}, {'name': 'unit', 'type': str, 'doc': 'The base unit of measurement (should be SI unit)', 'default': 'meters'}, *get_docval(TimeSeries.__init__, 'conversion', 'resolution', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'offset')) def __init__(self, **kwargs): """ Create a SpatialSeries TimeSeries dataset """ name, data, reference_frame, unit = popargs('name', 'data', 'reference_frame', 'unit', kwargs) super().__init__(name, data, unit, **kwargs) # NWB 2.5 restricts length of second dimension to be <= 3 allowed_data_shapes = ((None, ), (None, 1), (None, 2), (None, 3)) data_shape = get_data_shape(data) if not any(self._validate_data_shape(data_shape, a) for a in allowed_data_shapes): warnings.warn("SpatialSeries '%s' has data shape %s which is not compliant with NWB 2.5 and greater. " "The second dimension should have length <= 3 to represent at most x, y, z." % (name, str(data_shape))) self.reference_frame = reference_frame @staticmethod def _validate_data_shape(valshape, argshape): if not len(valshape) == len(argshape): return False for a, b in zip(valshape, argshape): if b not in (a, None): return False return True @register_class('BehavioralEpochs', CORE_NAMESPACE) class BehavioralEpochs(MultiContainerInterface): """ TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output of one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group "BehavioralTimeSeries". BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data. """ __clsconf__ = { 'add': 'add_interval_series', 'get': 'get_interval_series', 'create': 'create_interval_series', 'type': IntervalSeries, 'attr': 'interval_series' } @register_class('BehavioralEvents', CORE_NAMESPACE) class BehavioralEvents(MultiContainerInterface): """ TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details. """ __clsconf__ = { 'add': 'add_timeseries', 'get': 'get_timeseries', 'create': 'create_timeseries', 'type': TimeSeries, 'attr': 'time_series' } @register_class('BehavioralTimeSeries', CORE_NAMESPACE) class BehavioralTimeSeries(MultiContainerInterface): """ TimeSeries for storing Behavioral time series data. See description of BehavioralEpochs for more details. """ __clsconf__ = { 'add': 'add_timeseries', 'get': 'get_timeseries', 'create': 'create_timeseries', 'type': TimeSeries, 'attr': 'time_series' } @register_class('PupilTracking', CORE_NAMESPACE) class PupilTracking(MultiContainerInterface): """ Eye-tracking data, representing pupil size. """ __clsconf__ = { 'add': 'add_timeseries', 'get': 'get_timeseries', 'create': 'create_timeseries', 'type': TimeSeries, 'attr': 'time_series' } @register_class('EyeTracking', CORE_NAMESPACE) class EyeTracking(MultiContainerInterface): """ Eye-tracking data, representing direction of gaze. """ __clsconf__ = { 'add': 'add_spatial_series', 'get': 'get_spatial_series', 'create': 'create_spatial_series', 'type': SpatialSeries, 'attr': 'spatial_series' } @register_class('CompassDirection', CORE_NAMESPACE) class CompassDirection(MultiContainerInterface): """ With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees. """ __clsconf__ = { 'add': 'add_spatial_series', 'get': 'get_spatial_series', 'create': 'create_spatial_series', 'type': SpatialSeries, 'attr': 'spatial_series' } @register_class('Position', CORE_NAMESPACE) class Position(MultiContainerInterface): """ Position data, whether along the x, x/y or x/y/z axis. """ __clsconf__ = { 'add': 'add_spatial_series', 'get': 'get_spatial_series', 'create': 'create_spatial_series', 'type': SpatialSeries, 'attr': 'spatial_series' } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/core.py0000644000175100001730000001246014467767506015537 0ustar00runnerdockerfrom warnings import warn import numpy as np from hdmf import Container, Data from hdmf.container import AbstractContainer, MultiContainerInterface as hdmf_MultiContainerInterface, Table from hdmf.common import DynamicTable, DynamicTableRegion # noqa: F401 from hdmf.common import VectorData, VectorIndex, ElementIdentifiers # noqa: F401 from hdmf.utils import docval, popargs from hdmf.utils import LabelledDict # noqa: F401 from . import CORE_NAMESPACE, register_class def _not_parent(arg): return arg['name'] != 'parent' def prepend_string(string, prepend=' '): return prepend + prepend.join(string.splitlines(True)) class NWBMixin(AbstractContainer): _data_type_attr = 'neurodata_type' @docval({'name': 'neurodata_type', 'type': str, 'doc': 'the data_type to search for', 'default': None}) def get_ancestor(self, **kwargs): """ Traverse parent hierarchy and return first instance of the specified data_type """ neurodata_type = kwargs['neurodata_type'] return super().get_ancestor(data_type=neurodata_type) def _error_on_new_warn_on_construct(self, error_msg: str): """ Raise an error when a check is violated on instance creation. To ensure backwards compatibility, this method throws a warning instead of raising an error when reading from a file, ensuring that files with invalid data can be read. If error_msg is set to None the function will simply return without further action. """ if error_msg is None: return if not self._in_construct_mode: raise ValueError(error_msg) warn(error_msg) @register_class('NWBContainer', CORE_NAMESPACE) class NWBContainer(NWBMixin, Container): _fieldsname = '__nwbfields__' __nwbfields__ = tuple() @register_class('NWBDataInterface', CORE_NAMESPACE) class NWBDataInterface(NWBContainer): pass @register_class('NWBData', CORE_NAMESPACE) class NWBData(NWBMixin, Data): @docval({'name': 'name', 'type': str, 'doc': 'the name of this container'}, {'name': 'data', 'type': ('scalar_data', 'array_data', 'data', Data), 'doc': 'the source of the data'}) def __init__(self, **kwargs): super().__init__(**kwargs) self.__data = kwargs['data'] @property def data(self): return self.__data def __len__(self): return len(self.__data) def __getitem__(self, args): if isinstance(self.data, (tuple, list)) and isinstance(args, (tuple, list)): return [self.data[i] for i in args] return self.data[args] def append(self, arg): if isinstance(self.data, list): self.data.append(arg) elif isinstance(self.data, np.ndarray): self.__data = np.concatenate((self.__data, [arg])) else: msg = "NWBData cannot append to object of type '%s'" % type(self.__data) raise ValueError(msg) def extend(self, arg): if isinstance(self.data, list): self.data.extend(arg) elif isinstance(self.data, np.ndarray): self.__data = np.concatenate((self.__data, arg)) else: msg = "NWBData cannot extend object of type '%s'" % type(self.__data) raise ValueError(msg) @register_class('ScratchData', CORE_NAMESPACE) class ScratchData(NWBData): __nwbfields__ = ('description', ) @docval({'name': 'name', 'type': str, 'doc': 'the name of this container'}, {'name': 'data', 'type': ('scalar_data', 'array_data', 'data', Data), 'doc': 'the source of the data'}, {'name': 'notes', 'type': str, 'doc': 'notes about the data. This argument will be deprecated. Use description instead', 'default': ''}, {'name': 'description', 'type': str, 'doc': 'notes about the data', 'default': None}) def __init__(self, **kwargs): notes, description = popargs('notes', 'description', kwargs) super().__init__(**kwargs) if notes != '': warn('The `notes` argument of ScratchData.__init__ will be deprecated. Use description instead.', PendingDeprecationWarning) if notes != '' and description != '': raise ValueError('Cannot provide both notes and description to ScratchData.__init__. The description ' 'argument is recommended.') description = notes if not description: warn('ScratchData.description will be required in a future major release of PyNWB.', PendingDeprecationWarning) self.description = description @property def notes(self): warn('Use of ScratchData.notes will be deprecated. Use ScratchData.description instead.', PendingDeprecationWarning) return self.description @notes.setter def notes(self, value): warn('Use of ScratchData.notes will be deprecated. Use ScratchData.description instead.', PendingDeprecationWarning) self.description = value class NWBTable(Table): """Defined in PyNWB for API backward compatibility. See HDMF Table for details.""" pass class MultiContainerInterface(NWBDataInterface, hdmf_MultiContainerInterface): """Defined in PyNWB for API backward compatibility. See HDMF MultiContainterInterface for details.""" pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/device.py0000644000175100001730000000202014467767506016035 0ustar00runnerdockerfrom hdmf.utils import docval, popargs from . import register_class, CORE_NAMESPACE from .core import NWBContainer @register_class('Device', CORE_NAMESPACE) class Device(NWBContainer): """ Metadata about a data acquisition device, e.g., recording system, electrode, microscope. """ __nwbfields__ = ('name', 'description', 'manufacturer') @docval({'name': 'name', 'type': str, 'doc': 'the name of this device'}, {'name': 'description', 'type': str, 'doc': 'Description of the device (e.g., model, firmware version, processing software version, etc.)', 'default': None}, {'name': 'manufacturer', 'type': str, 'doc': 'the name of the manufacturer of this device', 'default': None}) def __init__(self, **kwargs): description, manufacturer = popargs('description', 'manufacturer', kwargs) super().__init__(**kwargs) self.description = description self.manufacturer = manufacturer ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/ecephys.py0000644000175100001730000004331514467767506016252 0ustar00runnerdockerimport warnings from collections.abc import Iterable from hdmf.common import DynamicTableRegion from hdmf.data_utils import DataChunkIterator, assertEqualShape from hdmf.utils import docval, popargs, get_docval, popargs_to_dict, get_data_shape from . import register_class, CORE_NAMESPACE from .base import TimeSeries from .core import NWBContainer, NWBDataInterface, MultiContainerInterface from .device import Device @register_class('ElectrodeGroup', CORE_NAMESPACE) class ElectrodeGroup(NWBContainer): """Defines a related group of electrodes.""" __nwbfields__ = ('name', 'description', 'location', 'device', 'position') @docval({'name': 'name', 'type': str, 'doc': 'the name of this electrode group'}, {'name': 'description', 'type': str, 'doc': 'description of this electrode group'}, {'name': 'location', 'type': str, 'doc': 'description of location of this electrode group'}, {'name': 'device', 'type': Device, 'doc': 'the device that was used to record from this electrode group'}, {'name': 'position', 'type': 'array_data', 'doc': 'stereotaxic position of this electrode group (x, y, z)', 'default': None}) def __init__(self, **kwargs): args_to_set = popargs_to_dict(('description', 'location', 'device', 'position'), kwargs) super().__init__(**kwargs) if args_to_set['position'] and len(args_to_set['position']) != 3: raise ValueError('ElectrodeGroup position argument must have three elements: x, y, z, but received: %s' % str(args_to_set['position'])) for key, val in args_to_set.items(): setattr(self, key, val) @register_class('ElectricalSeries', CORE_NAMESPACE) class ElectricalSeries(TimeSeries): """ Stores acquired voltage data from extracellular recordings. The data field of an ElectricalSeries is an int or float array storing data in Volts. TimeSeries::data array structure: [num times] [num channels] (or [num_times] for single electrode). """ __nwbfields__ = ({'name': 'electrodes', 'required_name': 'electrodes', 'doc': 'the electrodes that generated this electrical series', 'child': True}, 'channel_conversion', 'filtering') @docval(*get_docval(TimeSeries.__init__, 'name'), # required {'name': 'data', 'type': ('array_data', 'data', TimeSeries), # required 'shape': ((None, ), (None, None), (None, None, None)), 'doc': ('The data values. Can be 1D or 2D. The first dimension must be time. The second dimension ' 'represents electrodes/channels.')}, {'name': 'electrodes', 'type': DynamicTableRegion, # required 'doc': 'the table region corresponding to the electrodes from which this series was recorded'}, {'name': 'channel_conversion', 'type': ('array_data', 'data'), 'shape': (None,), 'doc': "Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the " "channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' " "attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * " "channel_conversion. This approach allows for both global and per-channel data conversion factors needed " "to support the storage of electrical recordings as native values generated by data acquisition systems. " "If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all" " channels.", 'default': None}, {'name': 'filtering', 'type': str, 'doc': "Filtering applied to all channels of the data. For example, if this ElectricalSeries represents " "high-pass-filtered data (also known as AP Band), then this value could be 'High-pass 4-pole Bessel " "filter at 500 Hz'. If this ElectricalSeries represents low-pass-filtered LFP data and the type of " "filter is unknown, then this value could be 'Low-pass filter at 300 Hz'. If a non-standard filter " "type is used, provide as much detail about the filter properties as possible.", 'default': None}, *get_docval(TimeSeries.__init__, 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'offset')) def __init__(self, **kwargs): args_to_set = popargs_to_dict(('electrodes', 'channel_conversion', 'filtering'), kwargs) data_shape = get_data_shape(kwargs['data'], strict_no_data_load=True) if ( data_shape is not None and len(data_shape) == 2 and data_shape[1] != len(args_to_set['electrodes'].data) ): if data_shape[0] == len(args_to_set['electrodes'].data): warnings.warn("%s '%s': The second dimension of data does not match the length of electrodes, " "but instead the first does. Data is oriented incorrectly and should be transposed." % (self.__class__.__name__, kwargs["name"])) else: warnings.warn("%s '%s': The second dimension of data does not match the length of electrodes. " "Your data may be transposed." % (self.__class__.__name__, kwargs["name"])) kwargs['unit'] = 'volts' # fixed value super().__init__(**kwargs) for key, val in args_to_set.items(): setattr(self, key, val) @register_class('SpikeEventSeries', CORE_NAMESPACE) class SpikeEventSeries(ElectricalSeries): """ Stores "snapshots" of spike events (i.e., threshold crossings) in data. This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describing how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode). """ __nwbfields__ = () @docval(*get_docval(ElectricalSeries.__init__, 'name', 'data'), # required {'name': 'timestamps', 'type': ('array_data', 'data', TimeSeries), # required 'doc': 'Timestamps for samples stored in data'}, *get_docval(ElectricalSeries.__init__, 'electrodes'), # required *get_docval(ElectricalSeries.__init__, 'resolution', 'conversion', 'comments', 'description', 'control', 'control_description', 'offset')) def __init__(self, **kwargs): data = kwargs['data'] timestamps = kwargs['timestamps'] if not (isinstance(data, TimeSeries) or isinstance(timestamps, TimeSeries)): if not (isinstance(data, DataChunkIterator) or isinstance(timestamps, DataChunkIterator)): if len(data) != len(timestamps): raise ValueError('Must provide the same number of timestamps and spike events') else: # TODO: add check when we have DataChunkIterators pass super().__init__(**kwargs) @register_class('EventDetection', CORE_NAMESPACE) class EventDetection(NWBDataInterface): """ Detected spike events from voltage trace(s). """ __nwbfields__ = ('detection_method', 'source_electricalseries', 'source_idx', 'times') @docval({'name': 'detection_method', 'type': str, 'doc': 'Description of how events were detected, such as voltage threshold, or dV/dT threshold, ' 'as well as relevant values.'}, {'name': 'source_electricalseries', 'type': ElectricalSeries, 'doc': 'The source electrophysiology data'}, {'name': 'source_idx', 'type': ('array_data', 'data'), 'doc': 'Indices (zero-based) into source ElectricalSeries::data array corresponding ' 'to time of event. Module description should define what is meant by time of event ' '(e.g., .25msec before action potential peak, zero-crossing time, etc). ' 'The index points to each event from the raw data'}, {'name': 'times', 'type': ('array_data', 'data'), 'doc': 'Timestamps of events, in Seconds'}, {'name': 'name', 'type': str, 'doc': 'the name of this container', 'default': 'EventDetection'}) def __init__(self, **kwargs): args_to_set = popargs_to_dict(('detection_method', 'source_electricalseries', 'source_idx', 'times'), kwargs) super().__init__(**kwargs) for key, val in args_to_set.items(): setattr(self, key, val) self.unit = 'seconds' # fixed value @register_class('EventWaveform', CORE_NAMESPACE) class EventWaveform(MultiContainerInterface): """ Spike data for spike events detected in raw data stored in this NWBFile, or events detect at acquisition """ __clsconf__ = { 'attr': 'spike_event_series', 'type': SpikeEventSeries, 'add': 'add_spike_event_series', 'get': 'get_spike_event_series', 'create': 'create_spike_event_series' } @register_class('Clustering', CORE_NAMESPACE) class Clustering(NWBDataInterface): """ DEPRECATED in favor of :py:meth:`~pynwb.misc.Units`. Specifies cluster event times and cluster metric for maximum ratio of waveform peak to RMS on any channel in cluster. """ __nwbfields__ = ( 'description', 'num', 'peak_over_rms', 'times' ) @docval({'name': 'description', 'type': str, 'doc': 'Description of clusters or clustering, (e.g. cluster 0 is noise, ' 'clusters curated using Klusters, etc).'}, {'name': 'num', 'type': ('array_data', 'data'), 'doc': 'Cluster number of each event.', 'shape': (None, )}, {'name': 'peak_over_rms', 'type': Iterable, 'shape': (None, ), 'doc': 'Maximum ratio of waveform peak to RMS on any channel in the cluster' '(provides a basic clustering metric).'}, {'name': 'times', 'type': ('array_data', 'data'), 'doc': 'Times of clustered events, in seconds.', 'shape': (None,)}, {'name': 'name', 'type': str, 'doc': 'the name of this container', 'default': 'Clustering'}) def __init__(self, **kwargs): warnings.warn("use pynwb.misc.Units or NWBFile.units instead", DeprecationWarning) args_to_set = popargs_to_dict(('description', 'num', 'peak_over_rms', 'times'), kwargs) super().__init__(**kwargs) args_to_set['peak_over_rms'] = list(args_to_set['peak_over_rms']) for key, val in args_to_set.items(): setattr(self, key, val) @register_class('ClusterWaveforms', CORE_NAMESPACE) class ClusterWaveforms(NWBDataInterface): """ DEPRECATED. `ClusterWaveforms` was deprecated in Oct 27, 2018 and will be removed in a future release. Please use the `Units` table to store waveform mean and standard deviation e.g. `NWBFile.units.add_unit(..., waveform_mean=..., waveform_sd=...)` Describe cluster waveforms by mean and standard deviation for at each sample. """ __nwbfields__ = ('clustering_interface', 'waveform_filtering', 'waveform_mean', 'waveform_sd') @docval({'name': 'clustering_interface', 'type': Clustering, 'doc': 'the clustered spike data used as input for computing waveforms'}, {'name': 'waveform_filtering', 'type': str, 'doc': 'filter applied to data before calculating mean and standard deviation'}, {'name': 'waveform_mean', 'type': Iterable, 'shape': (None, None), 'doc': 'the mean waveform for each cluster'}, {'name': 'waveform_sd', 'type': Iterable, 'shape': (None, None), 'doc': 'the standard deviations of waveforms for each cluster'}, {'name': 'name', 'type': str, 'doc': 'the name of this container', 'default': 'ClusterWaveforms'}) def __init__(self, **kwargs): warnings.warn("use pynwb.misc.Units or NWBFile.units instead", DeprecationWarning) args_to_set = popargs_to_dict(('clustering_interface', 'waveform_filtering', 'waveform_mean', 'waveform_sd'), kwargs) super().__init__(**kwargs) for key, val in args_to_set.items(): setattr(self, key, val) @register_class('LFP', CORE_NAMESPACE) class LFP(MultiContainerInterface): """ LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries description or comments field. """ __clsconf__ = [ {'attr': 'electrical_series', 'type': ElectricalSeries, 'add': 'add_electrical_series', 'get': 'get_electrical_series', 'create': 'create_electrical_series'}] @register_class('FilteredEphys', CORE_NAMESPACE) class FilteredEphys(MultiContainerInterface): """ Ephys data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. """ __clsconf__ = { 'attr': 'electrical_series', 'type': ElectricalSeries, 'add': 'add_electrical_series', 'get': 'get_electrical_series', 'create': 'create_electrical_series' } @register_class('FeatureExtraction', CORE_NAMESPACE) class FeatureExtraction(NWBDataInterface): """ Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEvent TimeSeries or other source. """ __nwbfields__ = ('description', {'name': 'electrodes', 'child': True}, 'times', 'features') @docval({'name': 'electrodes', 'type': DynamicTableRegion, 'doc': 'the table region corresponding to the electrodes from which this series was recorded'}, {'name': 'description', 'type': ('array_data', 'data'), 'doc': 'A description for each feature extracted', 'shape': (None, )}, {'name': 'times', 'type': ('array_data', 'data'), 'shape': (None, ), 'doc': 'The times of events that features correspond to'}, {'name': 'features', 'type': ('array_data', 'data'), 'shape': (None, None, None), 'doc': 'Features for each channel'}, {'name': 'name', 'type': str, 'doc': 'the name of this container', 'default': 'FeatureExtraction'}) def __init__(self, **kwargs): # get the inputs electrodes, description, times, features = popargs( 'electrodes', 'description', 'times', 'features', kwargs) # Validate the shape of the inputs # Validate event times compared to features shape_validators = [] shape_validators.append(assertEqualShape(data1=features, data2=times, axes1=0, axes2=0, name1='feature_shape', name2='times', ignore_undetermined=True)) # Validate electrodes compared to features shape_validators.append(assertEqualShape(data1=features, data2=electrodes, axes1=1, axes2=0, name1='feature_shape', name2='electrodes', ignore_undetermined=True)) # Valided description compared to features shape_validators.append(assertEqualShape(data1=features, data2=description, axes1=2, axes2=0, name1='feature_shape', name2='description', ignore_undetermined=True)) # Raise an error if any of the shapes do not match raise_error = False error_msg = "" for sv in shape_validators: raise_error |= not sv.result if not sv.result: error_msg += sv.message + "\n" if raise_error: raise ValueError(error_msg) # Initialize the object super().__init__(**kwargs) self.electrodes = electrodes self.description = description self.times = list(times) self.features = features ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/epoch.py0000644000175100001730000000724014467767506015705 0ustar00runnerdockerfrom bisect import bisect_left from hdmf.data_utils import DataIO from hdmf.common import DynamicTable from hdmf.utils import docval, getargs, popargs, get_docval from . import register_class, CORE_NAMESPACE from .base import TimeSeries, TimeSeriesReferenceVectorData, TimeSeriesReference @register_class('TimeIntervals', CORE_NAMESPACE) class TimeIntervals(DynamicTable): """ Table for storing Epoch data """ __defaultname__ = 'epochs' __columns__ = ( {'name': 'start_time', 'description': 'Start time of epoch, in seconds', 'required': True}, {'name': 'stop_time', 'description': 'Stop time of epoch, in seconds', 'required': True}, {'name': 'tags', 'description': 'user-defined tags', 'index': True}, {'name': 'timeseries', 'description': 'index into a TimeSeries object', 'index': True, 'class': TimeSeriesReferenceVectorData} ) @docval({'name': 'name', 'type': str, 'doc': 'name of this TimeIntervals'}, # required {'name': 'description', 'type': str, 'doc': 'Description of this TimeIntervals', 'default': "experimental intervals"}, *get_docval(DynamicTable.__init__, 'id', 'columns', 'colnames')) def __init__(self, **kwargs): super().__init__(**kwargs) @docval({'name': 'start_time', 'type': float, 'doc': 'Start time of epoch, in seconds'}, {'name': 'stop_time', 'type': float, 'doc': 'Stop time of epoch, in seconds'}, {'name': 'tags', 'type': (str, list, tuple), 'doc': 'user-defined tags used throughout time intervals', 'default': None}, {'name': 'timeseries', 'type': (list, tuple, TimeSeries), 'doc': 'the TimeSeries this epoch applies to', 'default': None}, allow_extra=True) def add_interval(self, **kwargs): tags, timeseries = popargs('tags', 'timeseries', kwargs) start_time, stop_time = getargs('start_time', 'stop_time', kwargs) rkwargs = dict(kwargs) if tags is not None: if isinstance(tags, str): tags = [s.strip() for s in tags.split(",") if not s.isspace()] rkwargs['tags'] = tags if not (timeseries is None or (isinstance(timeseries, (tuple, list)) and len(timeseries) == 0)): if isinstance(timeseries, TimeSeries): timeseries = [timeseries] tmp = list() for ts in timeseries: idx_start, count = self.__calculate_idx_count(start_time, stop_time, ts) tmp.append(TimeSeriesReference(idx_start, count, ts)) timeseries = tmp rkwargs['timeseries'] = timeseries return super().add_row(**rkwargs) def __calculate_idx_count(self, start_time, stop_time, ts_data): if isinstance(ts_data.timestamps, DataIO): ts_timestamps = ts_data.timestamps.data ts_starting_time = ts_data.starting_time ts_rate = ts_data.rate else: ts = ts_data ts_timestamps = ts.timestamps ts_starting_time = ts.starting_time ts_rate = ts.rate if ts_starting_time is not None and ts_rate: start_idx = int((start_time - ts_starting_time)*ts_rate) stop_idx = int((stop_time - ts_starting_time)*ts_rate) elif len(ts_timestamps) > 0: timestamps = ts_timestamps start_idx = bisect_left(timestamps, start_time) stop_idx = bisect_left(timestamps, stop_time) else: raise ValueError("TimeSeries object must have timestamps or starting_time and rate") count = stop_idx - start_idx idx_start = start_idx return int(idx_start), int(count) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/file.py0000644000175100001730000016057414467767506015540 0ustar00runnerdockerfrom datetime import datetime, timedelta from dateutil.tz import tzlocal from collections.abc import Iterable from warnings import warn import copy as _copy import numpy as np import pandas as pd from hdmf.common import DynamicTableRegion, DynamicTable from hdmf.container import HERDManager from hdmf.utils import docval, getargs, get_docval, popargs, popargs_to_dict, AllowPositional from . import register_class, CORE_NAMESPACE from .base import TimeSeries, ProcessingModule from .device import Device from .epoch import TimeIntervals from .ecephys import ElectrodeGroup from .icephys import (IntracellularElectrode, SweepTable, PatchClampSeries, IntracellularRecordingsTable, SimultaneousRecordingsTable, SequentialRecordingsTable, RepetitionsTable, ExperimentalConditionsTable) from .image import Images from .ophys import ImagingPlane from .ogen import OptogeneticStimulusSite from .misc import Units from .core import NWBContainer, NWBDataInterface, MultiContainerInterface, ScratchData, LabelledDict def _not_parent(arg): return arg['name'] != 'parent' @register_class('LabMetaData', CORE_NAMESPACE) class LabMetaData(NWBContainer): """ Container for storing lab-specific meta-data The LabMetaData class serves as a base type for defining lab specific meta-data. To define your own lab-specific metadata, create a Neurodata Extension (NDX) for NWB that defines the data to add. Using the LabMetaData container as a base type makes it easy to add your data to an NWBFile without having to modify the NWBFile type itself, since adding of LabMetaData is already implemented. For more details on how to create an extension see the :nwb_overview:`Extending NWB ` tutorial. """ @docval({'name': 'name', 'type': str, 'doc': 'name of lab metadata'}) def __init__(self, **kwargs): super().__init__(**kwargs) @register_class('Subject', CORE_NAMESPACE) class Subject(NWBContainer): """Subject information and metadata.""" __nwbfields__ = ( 'age', "age__reference", 'description', 'genotype', 'sex', 'species', 'subject_id', 'weight', 'date_of_birth', 'strain' ) @docval( { "name": "age", "type": (str, timedelta), "doc": 'The age of the subject. The ISO 8601 Duration format is recommended, e.g., "P90D" for 90 days old.' 'A timedelta will automatically be converted to The ISO 8601 Duration format.', "default": None, }, { "name": "age__reference", "type": str, "doc": "Age is with reference to this event. Can be 'birth' or 'gestational'. If reference is omitted, " "then 'birth' is implied. Value can be None when read from an NWB file with schema version " "2.0 to 2.5 where age__reference is missing.", "default": "birth", }, { "name": "description", "type": str, "doc": 'A description of the subject, e.g., "mouse A10".', "default": None, }, {'name': 'genotype', 'type': str, 'doc': 'The genotype of the subject, e.g., "Sst-IRES-Cre/wt;Ai32(RCL-ChR2(H134R)_EYFP)/wt".', 'default': None}, {'name': 'sex', 'type': str, 'doc': ('The sex of the subject. Using "F" (female), "M" (male), "U" (unknown), or "O" (other) ' 'is recommended.'), 'default': None}, {'name': 'species', 'type': str, 'doc': 'The species of the subject. The formal latin binomal name is recommended, e.g., "Mus musculus"', 'default': None}, {'name': 'subject_id', 'type': str, 'doc': 'A unique identifier for the subject, e.g., "A10"', 'default': None}, {'name': 'weight', 'type': (float, str), 'doc': ('The weight of the subject, including units. Using kilograms is recommended. e.g., "0.02 kg". ' 'If a float is provided, then the weight will be stored as "[value] kg".'), 'default': None}, {'name': 'date_of_birth', 'type': datetime, 'default': None, 'doc': 'The datetime of the date of birth. May be supplied instead of age.'}, {'name': 'strain', 'type': str, 'doc': 'The strain of the subject, e.g., "C57BL/6J"', 'default': None}, ) def __init__(self, **kwargs): keys_to_set = ( "age", "age__reference", "description", "genotype", "sex", "species", "subject_id", "weight", "date_of_birth", "strain", ) args_to_set = popargs_to_dict(keys_to_set, kwargs) super().__init__(name="subject", **kwargs) # NOTE when the Subject I/O mapper (see pynwb.io.file.py) reads an age__reference value of None from an # NWB 2.0-2.5 file, it sets the value to "unspecified" so that when Subject.__init__ is called, the incoming # age__reference value is NOT replaced by the default value ("birth") specified in the docval. # then we replace "unspecified" with None here. the user will never see the value "unspecified". # the ONLY way that age__reference can now be None is if it is read as None from an NWB 2.0-2.5 file. if self._in_construct_mode and args_to_set["age__reference"] == "unspecified": args_to_set["age__reference"] = None elif args_to_set["age__reference"] not in ("birth", "gestational"): raise ValueError("age__reference, if supplied, must be 'birth' or 'gestational'.") weight = args_to_set['weight'] if isinstance(weight, float): args_to_set['weight'] = str(weight) + ' kg' if isinstance(args_to_set["age"], timedelta): args_to_set["age"] = pd.Timedelta(args_to_set["age"]).isoformat() date_of_birth = args_to_set['date_of_birth'] if date_of_birth and date_of_birth.tzinfo is None: args_to_set['date_of_birth'] = _add_missing_timezone(date_of_birth) for key, val in args_to_set.items(): setattr(self, key, val) @register_class('NWBFile', CORE_NAMESPACE) class NWBFile(MultiContainerInterface, HERDManager): """ A representation of an NWB file. """ __clsconf__ = [ { 'attr': 'acquisition', 'add': '_add_acquisition_internal', 'type': (NWBDataInterface, DynamicTable), 'get': 'get_acquisition' }, { 'attr': 'analysis', 'add': 'add_analysis', 'type': (NWBContainer, DynamicTable), 'get': 'get_analysis' }, { 'attr': 'scratch', 'add': '_add_scratch', 'type': (DynamicTable, NWBContainer, ScratchData), 'get': '_get_scratch' }, { 'attr': 'stimulus', 'add': '_add_stimulus_internal', 'type': TimeSeries, 'get': 'get_stimulus' }, { 'attr': 'stimulus_template', 'add': '_add_stimulus_template_internal', 'type': (TimeSeries, Images), 'get': 'get_stimulus_template' }, { 'attr': 'processing', 'add': 'add_processing_module', 'type': ProcessingModule, 'create': 'create_processing_module', 'get': 'get_processing_module' }, { 'attr': 'devices', 'add': 'add_device', 'type': Device, 'create': 'create_device', 'get': 'get_device' }, { 'attr': 'electrode_groups', 'add': 'add_electrode_group', 'type': ElectrodeGroup, 'create': 'create_electrode_group', 'get': 'get_electrode_group' }, { 'attr': 'imaging_planes', 'add': 'add_imaging_plane', 'type': ImagingPlane, 'create': 'create_imaging_plane', 'get': 'get_imaging_plane' }, { 'attr': 'icephys_electrodes', 'add': 'add_icephys_electrode', 'type': IntracellularElectrode, 'create': 'create_icephys_electrode', 'get': 'get_icephys_electrode' }, { 'attr': 'ogen_sites', 'add': 'add_ogen_site', 'type': OptogeneticStimulusSite, 'create': 'create_ogen_site', 'get': 'get_ogen_site' }, { 'attr': 'intervals', 'add': 'add_time_intervals', 'type': TimeIntervals, 'create': 'create_time_intervals', 'get': 'get_time_intervals' }, { 'attr': 'lab_meta_data', 'add': 'add_lab_meta_data', 'type': LabMetaData, 'create': 'create_lab_meta_data', 'get': 'get_lab_meta_data' } ] __nwbfields__ = ({'name': 'session_description', 'settable': False}, {'name': 'identifier', 'settable': False}, {'name': 'session_start_time', 'settable': False}, {'name': 'timestamps_reference_time', 'settable': False}, {'name': 'file_create_date', 'settable': False}, 'experimenter', 'experiment_description', 'session_id', 'institution', 'keywords', 'notes', 'pharmacology', 'protocol', 'related_publications', 'slices', 'source_script', 'source_script_file_name', 'data_collection', 'surgery', 'virus', 'stimulus_notes', 'lab', {'name': 'electrodes', 'child': True, 'required_name': 'electrodes'}, {'name': 'epochs', 'child': True, 'required_name': 'epochs'}, {'name': 'trials', 'child': True, 'required_name': 'trials'}, {'name': 'units', 'child': True, 'required_name': 'units'}, {'name': 'subject', 'child': True, 'required_name': 'subject'}, {'name': 'sweep_table', 'child': True, 'required_name': 'sweep_table'}, {'name': 'invalid_times', 'child': True, 'required_name': 'invalid_times'}, 'epoch_tags', # icephys_filtering is temporary. /intracellular_ephys/filtering dataset will be deprecated {'name': 'icephys_filtering', 'settable': False}, {'name': 'intracellular_recordings', 'child': True, 'required_name': 'intracellular_recordings', 'doc': 'IntracellularRecordingsTable table to group together a stimulus and response ' 'from a single intracellular electrode and a single simultaneous recording.'}, {'name': 'icephys_simultaneous_recordings', 'child': True, 'required_name': 'simultaneous_recordings', 'doc': 'SimultaneousRecordingsTable table for grouping different intracellular recordings from' 'the IntracellularRecordingsTable table together that were recorded simultaneously ' 'from different electrodes'}, {'name': 'icephys_sequential_recordings', 'child': True, 'required_name': 'sequential_recordings', 'doc': 'A table for grouping different simultaneous intracellular recording from the ' 'SimultaneousRecordingsTable table together. This is typically used to group ' 'together simultaneous recordings where the a sequence of stimuli of the same ' 'type with varying parameters have been presented in a sequence.'}, {'name': 'icephys_repetitions', 'child': True, 'required_name': 'repetitions', 'doc': 'A table for grouping different intracellular recording sequential recordings together.' 'With each SweepSequence typically representing a particular type of stimulus, the ' 'RepetitionsTable table is typically used to group sets of stimuli applied in sequence.'}, {'name': 'icephys_experimental_conditions', 'child': True, 'required_name': 'experimental_conditions', 'doc': 'A table for grouping different intracellular recording repetitions together that ' 'belong to the same experimental experimental_conditions.'}) @docval({'name': 'session_description', 'type': str, 'doc': 'a description of the session where this data was generated'}, {'name': 'identifier', 'type': str, 'doc': 'a unique text identifier for the file'}, {'name': 'session_start_time', 'type': datetime, 'doc': 'the start date and time of the recording session'}, {'name': 'file_create_date', 'type': ('array_data', datetime), 'doc': 'the date and time the file was created and subsequent modifications made', 'default': None}, {'name': 'timestamps_reference_time', 'type': datetime, 'doc': 'date and time corresponding to time zero of all timestamps; defaults to value ' 'of session_start_time', 'default': None}, {'name': 'experimenter', 'type': (tuple, list, str), 'doc': 'name of person who performed experiment', 'default': None}, {'name': 'experiment_description', 'type': str, 'doc': 'general description of the experiment', 'default': None}, {'name': 'session_id', 'type': str, 'doc': 'lab-specific ID for the session', 'default': None}, {'name': 'institution', 'type': str, 'doc': 'institution(s) where experiment is performed', 'default': None}, {'name': 'keywords', 'type': 'array_data', 'doc': 'Terms to search over', 'default': None}, {'name': 'notes', 'type': str, 'doc': 'Notes about the experiment.', 'default': None}, {'name': 'pharmacology', 'type': str, 'doc': 'Description of drugs used, including how and when they were administered. ' 'Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.', 'default': None}, {'name': 'protocol', 'type': str, 'doc': 'Experimental protocol, if applicable. E.g., include IACUC protocol', 'default': None}, {'name': 'related_publications', 'type': (tuple, list, str), 'doc': 'Publication information.' 'PMID, DOI, URL, etc. If multiple, concatenate together and describe which is which. ' 'such as PMID, DOI, URL, etc', 'default': None}, {'name': 'slices', 'type': str, 'doc': 'Description of slices, including information about preparation ' 'thickness, orientation, temperature and bath solution', 'default': None}, {'name': 'source_script', 'type': str, 'doc': 'Script file used to create this NWB file.', 'default': None}, {'name': 'source_script_file_name', 'type': str, 'doc': 'Name of the source_script file', 'default': None}, {'name': 'data_collection', 'type': str, 'doc': 'Notes about data collection and analysis.', 'default': None}, {'name': 'surgery', 'type': str, 'doc': 'Narrative description about surgery/surgeries, including date(s) ' 'and who performed surgery.', 'default': None}, {'name': 'virus', 'type': str, 'doc': 'Information about virus(es) used in experiments, including virus ID, ' 'source, date made, injection location, volume, etc.', 'default': None}, {'name': 'stimulus_notes', 'type': str, 'doc': 'Notes about stimuli, such as how and where presented.', 'default': None}, {'name': 'lab', 'type': str, 'doc': 'lab where experiment was performed', 'default': None}, {'name': 'acquisition', 'type': (list, tuple), 'doc': 'Raw TimeSeries objects belonging to this NWBFile', 'default': None}, {'name': 'analysis', 'type': (list, tuple), 'doc': 'result of analysis', 'default': None}, {'name': 'stimulus', 'type': (list, tuple), 'doc': 'Stimulus TimeSeries objects belonging to this NWBFile', 'default': None}, {'name': 'stimulus_template', 'type': (list, tuple), 'doc': 'Stimulus template TimeSeries objects belonging to this NWBFile', 'default': None}, {'name': 'epochs', 'type': TimeIntervals, 'doc': 'Epoch objects belonging to this NWBFile', 'default': None}, {'name': 'epoch_tags', 'type': (tuple, list, set), 'doc': 'A sorted list of tags used across all epochs', 'default': set()}, {'name': 'trials', 'type': TimeIntervals, 'doc': 'A table containing trial data', 'default': None}, {'name': 'invalid_times', 'type': TimeIntervals, 'doc': 'A table containing times to be omitted from analysis', 'default': None}, {'name': 'intervals', 'type': (list, tuple), 'doc': 'any TimeIntervals tables storing time intervals', 'default': None}, {'name': 'units', 'type': Units, 'doc': 'A table containing unit metadata', 'default': None}, {'name': 'processing', 'type': (list, tuple), 'doc': 'ProcessingModule objects belonging to this NWBFile', 'default': None}, {'name': 'lab_meta_data', 'type': (list, tuple), 'default': None, 'doc': 'an extension that contains lab-specific meta-data'}, {'name': 'electrodes', 'type': DynamicTable, 'doc': 'the ElectrodeTable that belongs to this NWBFile', 'default': None}, {'name': 'electrode_groups', 'type': Iterable, 'doc': 'the ElectrodeGroups that belong to this NWBFile', 'default': None}, {'name': 'ic_electrodes', 'type': (list, tuple), 'doc': 'DEPRECATED use icephys_electrodes parameter instead. ' 'IntracellularElectrodes that belong to this NWBFile', 'default': None}, {'name': 'sweep_table', 'type': SweepTable, 'doc': 'the SweepTable that belong to this NWBFile', 'default': None}, {'name': 'imaging_planes', 'type': (list, tuple), 'doc': 'ImagingPlanes that belong to this NWBFile', 'default': None}, {'name': 'ogen_sites', 'type': (list, tuple), 'doc': 'OptogeneticStimulusSites that belong to this NWBFile', 'default': None}, {'name': 'devices', 'type': (list, tuple), 'doc': 'Device objects belonging to this NWBFile', 'default': None}, {'name': 'subject', 'type': Subject, 'doc': 'subject metadata', 'default': None}, {'name': 'scratch', 'type': (list, tuple), 'doc': 'scratch data', 'default': None}, {'name': 'icephys_electrodes', 'type': (list, tuple), 'doc': 'IntracellularElectrodes that belong to this NWBFile.', 'default': None}, {'name': 'icephys_filtering', 'type': str, 'default': None, 'doc': '[DEPRECATED] Use IntracellularElectrode.filtering instead. Description of filtering used.'}, {'name': 'intracellular_recordings', 'type': IntracellularRecordingsTable, 'default': None, 'doc': 'the IntracellularRecordingsTable table that belongs to this NWBFile'}, {'name': 'icephys_simultaneous_recordings', 'type': SimultaneousRecordingsTable, 'default': None, 'doc': 'the SimultaneousRecordingsTable table that belongs to this NWBFile'}, {'name': 'icephys_sequential_recordings', 'type': SequentialRecordingsTable, 'default': None, 'doc': 'the SequentialRecordingsTable table that belongs to this NWBFile'}, {'name': 'icephys_repetitions', 'type': RepetitionsTable, 'default': None, 'doc': 'the RepetitionsTable table that belongs to this NWBFile'}, {'name': 'icephys_experimental_conditions', 'type': ExperimentalConditionsTable, 'default': None, 'doc': 'the ExperimentalConditionsTable table that belongs to this NWBFile'}) def __init__(self, **kwargs): keys_to_set = [ 'session_description', 'identifier', 'session_start_time', 'experimenter', 'file_create_date', 'ic_electrodes', 'icephys_electrodes', 'related_publications', 'timestamps_reference_time', 'acquisition', 'analysis', 'stimulus', 'stimulus_template', 'keywords', 'processing', 'epoch_tags', 'electrodes', 'electrode_groups', 'devices', 'imaging_planes', 'ogen_sites', 'intervals', 'subject', 'sweep_table', 'lab_meta_data', 'epochs', 'trials', 'invalid_times', 'units', 'scratch', 'experiment_description', 'session_id', 'lab', 'institution', 'data_collection', 'notes', 'pharmacology', 'protocol', 'slices', 'source_script', 'source_script_file_name', 'surgery', 'virus', 'stimulus_notes', 'icephys_filtering', # DEPRECATION warning will be raised in the setter when calling setattr in the loop 'intracellular_recordings', 'icephys_simultaneous_recordings', 'icephys_sequential_recordings', 'icephys_repetitions', 'icephys_experimental_conditions' ] args_to_set = popargs_to_dict(keys_to_set, kwargs) kwargs['name'] = 'root' super().__init__(**kwargs) # add timezone to session_start_time if missing session_start_time = args_to_set['session_start_time'] if session_start_time.tzinfo is None: args_to_set['session_start_time'] = _add_missing_timezone(session_start_time) # set timestamps_reference_time to session_start_time if not provided # if provided, ensure that it has a timezone timestamps_reference_time = args_to_set['timestamps_reference_time'] if timestamps_reference_time is None: args_to_set['timestamps_reference_time'] = args_to_set['session_start_time'] elif timestamps_reference_time.tzinfo is None: raise ValueError("'timestamps_reference_time' must be a timezone-aware datetime object.") # convert file_create_date to list and add timezone if missing file_create_date = args_to_set['file_create_date'] if file_create_date is None: file_create_date = datetime.now(tzlocal()) if isinstance(file_create_date, datetime): file_create_date = [file_create_date] args_to_set['file_create_date'] = list(map(_add_missing_timezone, file_create_date)) # backwards-compatibility code for ic_electrodes / icephys_electrodes icephys_electrodes = args_to_set['icephys_electrodes'] ic_electrodes = args_to_set['ic_electrodes'] if icephys_electrodes is None and ic_electrodes is not None: warn("Use of the ic_electrodes parameter is deprecated. " "Use the icephys_electrodes parameter instead", DeprecationWarning) args_to_set['icephys_electrodes'] = ic_electrodes args_to_set.pop('ic_electrodes') # do not set this arg # convert single experimenter to tuple experimenter = args_to_set['experimenter'] if isinstance(experimenter, str): args_to_set['experimenter'] = (experimenter,) # convert single related_publications to tuple related_pubs = args_to_set['related_publications'] if isinstance(related_pubs, str): args_to_set['related_publications'] = (related_pubs,) # ensure source_script is provided if source_script_file_name is provided if args_to_set['source_script'] is None and args_to_set['source_script_file_name'] is not None: raise ValueError("'source_script' cannot be None when 'source_script_file_name' is set") # these attributes have no setters and can only be set using self.fields keys_to_set_via_fields = ( 'session_description', 'identifier', 'session_start_time', 'timestamps_reference_time', 'file_create_date' ) args_to_set_via_fields = popargs_to_dict(keys_to_set_via_fields, args_to_set) for key, val in args_to_set_via_fields.items(): self.fields[key] = val for key, val in args_to_set.items(): setattr(self, key, val) self.__obj = None def all_children(self): stack = [self] ret = list() self.__obj = LabelledDict(label='all_objects', key_attr='object_id') while len(stack): n = stack.pop() ret.append(n) if n.object_id is not None: self.__obj[n.object_id] = n else: warn('%s "%s" does not have an object_id' % (n.neurodata_type, n.name)) if hasattr(n, 'children'): for c in n.children: stack.append(c) return ret @property def objects(self): if self.__obj is None: self.all_children() return self.__obj @property def modules(self): warn("NWBFile.modules has been replaced by NWBFile.processing.", DeprecationWarning) return self.processing @property def ec_electrode_groups(self): warn("NWBFile.ec_electrode_groups has been replaced by NWBFile.electrode_groups.", DeprecationWarning) return self.electrode_groups @property def ec_electrodes(self): warn("NWBFile.ec_electrodes has been replaced by NWBFile.electrodes.", DeprecationWarning) return self.electrodes @property def ic_electrodes(self): warn("NWBFile.ic_electrodes has been replaced by NWBFile.icephys_electrodes.", DeprecationWarning) return self.icephys_electrodes @property def icephys_filtering(self): return self.fields.get('icephys_filtering') @icephys_filtering.setter def icephys_filtering(self, val): if val is not None: warn("Use of icephys_filtering is deprecated. Use the IntracellularElectrode.filtering field instead", DeprecationWarning) self.fields['icephys_filtering'] = val def add_ic_electrode(self, *args, **kwargs): """ This method is deprecated and will be removed in future versions. Please use :py:meth:`~pynwb.file.NWBFile.add_icephys_electrode` instead """ warn("NWBFile.add_ic_electrode has been replaced by NWBFile.add_icephys_electrode.", DeprecationWarning) return self.add_icephys_electrode(*args, **kwargs) def create_ic_electrode(self, *args, **kwargs): """ This method is deprecated and will be removed in future versions. Please use :py:meth:`~pynwb.file.NWBFile.create_icephys_electrode` instead """ warn("NWBFile.create_ic_electrode has been replaced by NWBFile.create_icephys_electrode.", DeprecationWarning) return self.create_icephys_electrode(*args, **kwargs) def get_ic_electrode(self, *args, **kwargs): """ This method is deprecated and will be removed in future versions. Please use :py:meth:`~pynwb.file.NWBFile.get_icephys_electrode` instead """ warn("NWBFile.get_ic_electrode has been replaced by NWBFile.get_icephys_electrode.", DeprecationWarning) return self.get_icephys_electrode(*args, **kwargs) def __check_epochs(self): if self.epochs is None: self.epochs = TimeIntervals(name='epochs', description='experimental epochs') @docval(*get_docval(TimeIntervals.add_column)) def add_epoch_column(self, **kwargs): """ Add a column to the epoch table. See :py:meth:`~pynwb.core.TimeIntervals.add_column` for more details """ self.__check_epochs() self.epoch_tags.update(kwargs.pop('tags', list())) self.epochs.add_column(**kwargs) def add_epoch_metadata_column(self, *args, **kwargs): """ This method is deprecated and will be removed in future versions. Please use :py:meth:`~pynwb.file.NWBFile.add_epoch_column` instead """ raise DeprecationWarning("Please use NWBFile.add_epoch_column") @docval(*get_docval(TimeIntervals.add_interval), allow_extra=True) def add_epoch(self, **kwargs): """ Creates a new Epoch object. Epochs are used to track intervals in an experiment, such as exposure to a certain type of stimuli (an interval where orientation gratings are shown, or of sparse noise) or a different paradigm (a rat exploring an enclosure versus sleeping between explorations) """ self.__check_epochs() if kwargs['tags'] is not None: self.epoch_tags.update(kwargs['tags']) self.epochs.add_interval(**kwargs) def __check_electrodes(self): if self.electrodes is None: self.electrodes = ElectrodeTable() @docval(*get_docval(DynamicTable.add_column)) def add_electrode_column(self, **kwargs): """ Add a column to the electrode table. See :py:meth:`~hdmf.common.table.DynamicTable.add_column` for more details """ self.__check_electrodes() self.electrodes.add_column(**kwargs) @docval({'name': 'x', 'type': float, 'doc': 'the x coordinate of the position (+x is posterior)', 'default': None}, {'name': 'y', 'type': float, 'doc': 'the y coordinate of the position (+y is inferior)', 'default': None}, {'name': 'z', 'type': float, 'doc': 'the z coordinate of the position (+z is right)', 'default': None}, {'name': 'imp', 'type': float, 'doc': 'the impedance of the electrode, in ohms', 'default': None}, {'name': 'location', 'type': str, 'doc': 'the location of electrode within the subject e.g. brain region. Required.', 'default': None}, {'name': 'filtering', 'type': str, 'doc': 'description of hardware filtering, including the filter name and frequency cutoffs', 'default': None}, {'name': 'group', 'type': ElectrodeGroup, 'doc': 'the ElectrodeGroup object to add to this NWBFile. Required.', 'default': None}, {'name': 'id', 'type': int, 'doc': 'a unique identifier for the electrode', 'default': None}, {'name': 'rel_x', 'type': float, 'doc': 'the x coordinate within the electrode group', 'default': None}, {'name': 'rel_y', 'type': float, 'doc': 'the y coordinate within the electrode group', 'default': None}, {'name': 'rel_z', 'type': float, 'doc': 'the z coordinate within the electrode group', 'default': None}, {'name': 'reference', 'type': str, 'doc': 'Description of the reference electrode and/or reference scheme\ used for this electrode, e.g.,"stainless steel skull screw" or "online common average referencing". ', 'default': None}, {'name': 'enforce_unique_id', 'type': bool, 'doc': 'enforce that the id in the table must be unique', 'default': True}, allow_extra=True, allow_positional=AllowPositional.WARNING) def add_electrode(self, **kwargs): """ Add an electrode to the electrodes table. See :py:meth:`~hdmf.common.table.DynamicTable.add_row` for more details. Required fields are *location* and *group* and any columns that have been added (through calls to `add_electrode_columns`). """ self.__check_electrodes() d = _copy.copy(kwargs['data']) if kwargs.get('data') is not None else kwargs # NOTE location and group are required arguments. in PyNWB 2.1.0 we made x, y, z optional arguments, and # in order to avoid breaking API changes, the order of the arguments needed to be maintained even though # these optional arguments came before the required arguments, so in docval these required arguments are # displayed as optional when really they are required. this should be changed when positional arguments # are not allowed if not d['location']: raise ValueError("The 'location' argument is required when creating an electrode.") if not kwargs['group']: raise ValueError("The 'group' argument is required when creating an electrode.") if d.get('group_name', None) is None: d['group_name'] = d['group'].name new_cols = [('x', 'the x coordinate of the position (+x is posterior)'), ('y', 'the y coordinate of the position (+y is inferior)'), ('z', 'the z coordinate of the position (+z is right)'), ('imp', 'the impedance of the electrode, in ohms'), ('filtering', 'description of hardware filtering, including the filter name and frequency cutoffs'), ('rel_x', 'the x coordinate within the electrode group'), ('rel_y', 'the y coordinate within the electrode group'), ('rel_z', 'the z coordinate within the electrode group'), ('reference', 'Description of the reference electrode and/or reference scheme used for this \ electrode, e.g.,"stainless steel skull screw" or "online common average referencing".') ] # add column if the arg is supplied and column does not yet exist # do not pass arg to add_row if arg is not supplied for col_name, col_doc in new_cols: if kwargs[col_name] is not None: if col_name not in self.electrodes: self.electrodes.add_column(col_name, col_doc) else: d.pop(col_name) # remove args from d if not set self.electrodes.add_row(**d) @docval({'name': 'region', 'type': (slice, list, tuple), 'doc': 'the indices of the table'}, {'name': 'description', 'type': str, 'doc': 'a brief description of what this electrode is'}, {'name': 'name', 'type': str, 'doc': 'the name of this container', 'default': 'electrodes'}) def create_electrode_table_region(self, **kwargs): if self.electrodes is None: msg = "no electrodes available. add electrodes before creating a region" raise RuntimeError(msg) region = getargs('region', kwargs) for idx in region: if idx < 0 or idx >= len(self.electrodes): raise IndexError('The index ' + str(idx) + ' is out of range for the ElectrodeTable of length ' + str(len(self.electrodes))) desc = getargs('description', kwargs) name = getargs('name', kwargs) return DynamicTableRegion(name=name, data=region, description=desc, table=self.electrodes) def __check_units(self): if self.units is None: self.units = Units(name='units', description='Autogenerated by NWBFile') @docval(*get_docval(Units.add_column)) def add_unit_column(self, **kwargs): """ Add a column to the unit table. See :py:meth:`~hdmf.common.table.DynamicTable.add_column` for more details """ self.__check_units() self.units.add_column(**kwargs) @docval(*get_docval(Units.add_unit), allow_extra=True) def add_unit(self, **kwargs): """ Add a unit to the unit table. See :py:meth:`~hdmf.common.table.DynamicTable.add_row` for more details. """ self.__check_units() self.units.add_unit(**kwargs) def __check_trials(self): if self.trials is None: self.trials = TimeIntervals(name='trials', description='experimental trials') @docval(*get_docval(DynamicTable.add_column)) def add_trial_column(self, **kwargs): """ Add a column to the trial table. See :py:meth:`~hdmf.common.table.DynamicTable.add_column` for more details """ self.__check_trials() self.trials.add_column(**kwargs) @docval(*get_docval(TimeIntervals.add_interval), allow_extra=True) def add_trial(self, **kwargs): """ Add a trial to the trial table. See :py:meth:`~hdmf.common.table.DynamicTable.add_interval` for more details. Required fields are *start_time*, *stop_time*, and any columns that have been added (through calls to `add_trial_columns`). """ self.__check_trials() self.trials.add_interval(**kwargs) def __check_invalid_times(self): if self.invalid_times is None: self.invalid_times = TimeIntervals( name='invalid_times', description='time intervals to be removed from analysis' ) @docval(*get_docval(DynamicTable.add_column)) def add_invalid_times_column(self, **kwargs): """ Add a column to the invalid times table. See :py:meth:`~hdmf.common.table.DynamicTable.add_column` for more details """ self.__check_invalid_times() self.invalid_times.add_column(**kwargs) @docval(*get_docval(TimeIntervals.add_interval), allow_extra=True) def add_invalid_time_interval(self, **kwargs): """ Add a time interval to the invalid times table. See :py:meth:`~hdmf.common.table.DynamicTable.add_row` for more details. Required fields are *start_time*, *stop_time*, and any columns that have been added (through calls to `add_invalid_times_columns`). """ self.__check_invalid_times() self.invalid_times.add_interval(**kwargs) @docval({'name': 'electrode_table', 'type': DynamicTable, 'doc': 'the ElectrodeTable for this file'}) def set_electrode_table(self, **kwargs): """ Set the electrode table of this NWBFile to an existing ElectrodeTable """ if self.electrodes is not None: msg = 'ElectrodeTable already exists, cannot overwrite' raise ValueError(msg) electrode_table = getargs('electrode_table', kwargs) self.electrodes = electrode_table def _check_sweep_table(self): """ Create a SweepTable if not yet done. """ if self.sweep_table is None: self.sweep_table = SweepTable(name='sweep_table') def _update_sweep_table(self, nwbdata): """ Add all PatchClampSeries with a valid sweep number to the sweep_table """ if isinstance(nwbdata, PatchClampSeries): if nwbdata.sweep_number is not None: self._check_sweep_table() self.sweep_table.add_entry(nwbdata) @docval({'name': 'nwbdata', 'type': (NWBDataInterface, DynamicTable)}, {'name': 'use_sweep_table', 'type': bool, 'default': False, 'doc': 'Use the deprecated SweepTable'}) def add_acquisition(self, **kwargs): nwbdata = popargs('nwbdata', kwargs) self._add_acquisition_internal(nwbdata) use_sweep_table = popargs('use_sweep_table', kwargs) if use_sweep_table: self._update_sweep_table(nwbdata) @docval({'name': 'timeseries', 'type': TimeSeries}, {'name': 'use_sweep_table', 'type': bool, 'default': False, 'doc': 'Use the deprecated SweepTable'}) def add_stimulus(self, **kwargs): timeseries = popargs('timeseries', kwargs) self._add_stimulus_internal(timeseries) use_sweep_table = popargs('use_sweep_table', kwargs) if use_sweep_table: self._update_sweep_table(timeseries) @docval({'name': 'timeseries', 'type': (TimeSeries, Images)}, {'name': 'use_sweep_table', 'type': bool, 'default': False, 'doc': 'Use the deprecated SweepTable'}) def add_stimulus_template(self, **kwargs): timeseries = popargs('timeseries', kwargs) self._add_stimulus_template_internal(timeseries) use_sweep_table = popargs('use_sweep_table', kwargs) if use_sweep_table: self._update_sweep_table(timeseries) @docval(returns='The NWBFile.intracellular_recordings table', rtype=IntracellularRecordingsTable) def get_intracellular_recordings(self): """ Get the NWBFile.intracellular_recordings table. In contrast to NWBFile.intracellular_recordings, this function will create the IntracellularRecordingsTable table if not yet done, whereas NWBFile.intracellular_recordings will return None if the table is currently not being used. """ if self.intracellular_recordings is None: self.intracellular_recordings = IntracellularRecordingsTable() return self.intracellular_recordings @docval(*get_docval(IntracellularRecordingsTable.add_recording), returns='Integer index of the row that was added to IntracellularRecordingsTable', rtype=int, allow_extra=True) def add_intracellular_recording(self, **kwargs): """ Add a intracellular recording to the intracellular_recordings table. If the electrode, stimulus, and/or response do not exist yet in the NWBFile, then they will be added to this NWBFile before adding them to the table. Note: For more complex organization of intracellular recordings you may also be interested in the related SimultaneousRecordingsTable, SequentialRecordingsTable, RepetitionsTable, and ExperimentalConditionsTable tables and the related functions of NWBFile: add_icephys_simultaneous_recording, add_icephys_sequential_recording, add_icephys_repetition, and add_icephys_experimental_condition. """ # Add the stimulus, response, and electrode to the file if they don't exist yet stimulus, response, electrode = getargs('stimulus', 'response', 'electrode', kwargs) if (stimulus is not None and (stimulus.name not in self.stimulus and stimulus.name not in self.stimulus_template)): self.add_stimulus(stimulus, use_sweep_table=False) if response is not None and response.name not in self.acquisition: self.add_acquisition(response, use_sweep_table=False) if electrode is not None and electrode.name not in self.icephys_electrodes: self.add_icephys_electrode(electrode) # make sure the intracellular recordings table exists and if not create it using get_intracellular_recordings # Add the recoding to the intracellular_recordings table return self.get_intracellular_recordings().add_recording(**kwargs) @docval(returns='The NWBFile.icephys_simultaneous_recordings table', rtype=SimultaneousRecordingsTable) def get_icephys_simultaneous_recordings(self): """ Get the NWBFile.icephys_simultaneous_recordings table. In contrast to NWBFile.icephys_simultaneous_recordings, this function will create the SimultaneousRecordingsTable table if not yet done, whereas NWBFile.icephys_simultaneous_recordings will return None if the table is currently not being used. """ if self.icephys_simultaneous_recordings is None: self.icephys_simultaneous_recordings = SimultaneousRecordingsTable(self.get_intracellular_recordings()) return self.icephys_simultaneous_recordings @docval(*get_docval(SimultaneousRecordingsTable.add_simultaneous_recording), returns='Integer index of the row that was added to SimultaneousRecordingsTable', rtype=int, allow_extra=True) def add_icephys_simultaneous_recording(self, **kwargs): """ Add a new simultaneous recording to the icephys_simultaneous_recordings table """ return self.get_icephys_simultaneous_recordings().add_simultaneous_recording(**kwargs) @docval(returns='The NWBFile.icephys_sequential_recordings table', rtype=SequentialRecordingsTable) def get_icephys_sequential_recordings(self): """ Get the NWBFile.icephys_sequential_recordings table. In contrast to NWBFile.icephys_sequential_recordings, this function will create the IntracellularRecordingsTable table if not yet done, whereas NWBFile.icephys_sequential_recordings will return None if the table is currently not being used. """ if self.icephys_sequential_recordings is None: self.icephys_sequential_recordings = SequentialRecordingsTable(self.get_icephys_simultaneous_recordings()) return self.icephys_sequential_recordings @docval(*get_docval(SequentialRecordingsTable.add_sequential_recording), returns='Integer index of the row that was added to SequentialRecordingsTable', rtype=int, allow_extra=True) def add_icephys_sequential_recording(self, **kwargs): """ Add a new sequential recording to the icephys_sequential_recordings table """ self.get_icephys_sequential_recordings() return self.icephys_sequential_recordings.add_sequential_recording(**kwargs) @docval(returns='The NWBFile.icephys_repetitions table', rtype=RepetitionsTable) def get_icephys_repetitions(self): """ Get the NWBFile.icephys_repetitions table. In contrast to NWBFile.icephys_repetitions, this function will create the RepetitionsTable table if not yet done, whereas NWBFile.icephys_repetitions will return None if the table is currently not being used. """ if self.icephys_repetitions is None: self.icephys_repetitions = RepetitionsTable(self.get_icephys_sequential_recordings()) return self.icephys_repetitions @docval(*get_docval(RepetitionsTable.add_repetition), returns='Integer index of the row that was added to RepetitionsTable', rtype=int, allow_extra=True) def add_icephys_repetition(self, **kwargs): """ Add a new repetition to the RepetitionsTable table """ return self.get_icephys_repetitions().add_repetition(**kwargs) @docval(returns='The NWBFile.icephys_experimental_conditions table', rtype=ExperimentalConditionsTable) def get_icephys_experimental_conditions(self): """ Get the NWBFile.icephys_experimental_conditions table. In contrast to NWBFile.icephys_experimental_conditions, this function will create the RepetitionsTable table if not yet done, whereas NWBFile.icephys_experimental_conditions will return None if the table is currently not being used. """ if self.icephys_experimental_conditions is None: self.icephys_experimental_conditions = ExperimentalConditionsTable(self.get_icephys_repetitions()) return self.icephys_experimental_conditions @docval(*get_docval(ExperimentalConditionsTable.add_experimental_condition), returns='Integer index of the row that was added to ExperimentalConditionsTable', rtype=int, allow_extra=True) def add_icephys_experimental_condition(self, **kwargs): """ Add a new condition to the ExperimentalConditionsTable table """ return self.get_icephys_experimental_conditions().add_experimental_condition(**kwargs) def get_icephys_meta_parent_table(self): """ Get the top-most table in the intracellular ephys metadata table hierarchy that exists in this NWBFile. The intracellular ephys metadata consists of a hierarchy of DynamicTables, i.e., experimental_conditions --> repetitions --> sequential_recordings --> simultaneous_recordings --> intracellular_recordings etc. In a given NWBFile not all tables may exist. This convenience functions returns the top-most table that exists in this file. E.g., if the file contains only the simultaneous_recordings and intracellular_recordings tables then the function would return the simultaneous_recordings table. Similarly, if the file contains all tables then it will return the experimental_conditions table. :returns: DynamicTable object or None """ if self.icephys_experimental_conditions is not None: return self.icephys_experimental_conditions elif self.icephys_repetitions is not None: return self.icephys_repetitions elif self.icephys_sequential_recordings is not None: return self.icephys_sequential_recordings elif self.icephys_simultaneous_recordings is not None: return self.icephys_simultaneous_recordings elif self.intracellular_recordings is not None: return self.intracellular_recordings else: return None @docval({'name': 'data', 'type': ('scalar_data', np.ndarray, list, tuple, pd.DataFrame, DynamicTable, NWBContainer, ScratchData), 'doc': 'The data to add to the scratch space.'}, {'name': 'name', 'type': str, 'doc': 'The name of the data. Required only when passing in a scalar, numpy.ndarray, list, or tuple', 'default': None}, {'name': 'notes', 'type': str, 'doc': ('Notes to add to the data. Only used when passing in numpy.ndarray, list, or tuple. This ' 'argument is not recommended. Use the `description` argument instead.'), 'default': None}, {'name': 'table_description', 'type': str, 'doc': ('Description for the internal DynamicTable used to store a pandas.DataFrame. This ' 'argument is not recommended. Use the `description` argument instead.'), 'default': ''}, {'name': 'description', 'type': str, 'doc': ('Description of the data. Required only when passing in a scalar, numpy.ndarray, ' 'list, tuple, or pandas.DataFrame. Ignored when passing in an NWBContainer, ' 'DynamicTable, or ScratchData object.'), 'default': None}) def add_scratch(self, **kwargs): '''Add data to the scratch space''' data, name, notes, table_description, description = getargs('data', 'name', 'notes', 'table_description', 'description', kwargs) if notes is not None or table_description != '': warn('Use of the `notes` or `table_description` argument will be removed in a future version of PyNWB. ' 'Use the `description` argument instead.', PendingDeprecationWarning) if description is not None: raise ValueError('Cannot call add_scratch with (notes or table_description) and description') if isinstance(data, (str, int, float, bytes, np.ndarray, list, tuple, pd.DataFrame)): if name is None: msg = ('A name is required for NWBFile.add_scratch when adding a scalar, numpy.ndarray, ' 'list, tuple, or pandas.DataFrame as scratch data.') raise ValueError(msg) if isinstance(data, pd.DataFrame): if table_description != '': description = table_description # remove after deprecation if description is None: msg = ('A description is required for NWBFile.add_scratch when adding a scalar, numpy.ndarray, ' 'list, tuple, or pandas.DataFrame as scratch data.') raise ValueError(msg) data = DynamicTable.from_dataframe(df=data, name=name, table_description=description) else: if notes is not None: description = notes # remove after deprecation if description is None: msg = ('A description is required for NWBFile.add_scratch when adding a scalar, numpy.ndarray, ' 'list, tuple, or pandas.DataFrame as scratch data.') raise ValueError(msg) data = ScratchData(name=name, data=data, description=description) else: if name is not None: warn('The name argument is ignored when adding an NWBContainer, ScratchData, or ' 'DynamicTable to scratch.') if description is not None: warn('The description argument is ignored when adding an NWBContainer, ScratchData, or ' 'DynamicTable to scratch.') return self._add_scratch(data) @docval({'name': 'name', 'type': str, 'doc': 'the name of the object to get'}, {'name': 'convert', 'type': bool, 'doc': 'return the original data, not the NWB object', 'default': True}) def get_scratch(self, **kwargs): '''Get data from the scratch space''' name, convert = getargs('name', 'convert', kwargs) ret = self._get_scratch(name) if convert: if isinstance(ret, DynamicTable): ret = ret.to_dataframe() elif isinstance(ret, ScratchData): ret = np.asarray(ret.data) return ret def copy(self): """ Shallow copy of an NWB file. Useful for linking across files. """ kwargs = self.fields.copy() for key in self.fields: if isinstance(self.fields[key], LabelledDict): kwargs[key] = list(self.fields[key].values()) # HDF5 object references cannot point to objects external to the file. Both DynamicTables such as TimeIntervals # contain such object references and types such as ElectricalSeries contain references to DynamicTables. # Below, copy the table and link to the columns so that object references work. fields_to_copy = ['electrodes', 'epochs', 'trials', 'units', 'sweep_table', 'invalid_times'] for field in fields_to_copy: if field in kwargs: if isinstance(self.fields[field], DynamicTable): kwargs[field] = self.fields[field].copy() else: warn('Cannot copy child of NWBFile that is not a DynamicTable: %s' % field) # handle dictionaries of DynamicTables dt_to_copy = ['scratch', 'intervals'] for dt in dt_to_copy: if dt in kwargs: kwargs[dt] = [v.copy() if isinstance(v, DynamicTable) else v for v in kwargs[dt]] return NWBFile(**kwargs) def _add_missing_timezone(date): """ Add local timezone information on a datetime object if it is missing. """ if not isinstance(date, datetime): raise ValueError("require datetime object") if date.tzinfo is None: warn("Date is missing timezone information. Updating to local timezone.", stacklevel=2) return date.replace(tzinfo=tzlocal()) return date def _tablefunc(table_name, description, columns): t = DynamicTable(name=table_name, description=description) for c in columns: if isinstance(c, tuple): t.add_column(c[0], c[1]) elif isinstance(c, str): t.add_column(c) else: raise ValueError("Elements of 'columns' must be str or tuple") return t def ElectrodeTable(name='electrodes', description='metadata about extracellular electrodes'): return _tablefunc(name, description, [('location', 'the location of channel within the subject e.g. brain region'), ('group', 'a reference to the ElectrodeGroup this electrode is a part of'), ('group_name', 'the name of the ElectrodeGroup this electrode is a part of') ] ) def TrialTable(name='trials', description='metadata about experimental trials'): return _tablefunc(name, description, ['start_time', 'stop_time']) def InvalidTimesTable(name='invalid_times', description='time intervals to be removed from analysis'): return _tablefunc(name, description, ['start_time', 'stop_time']) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/icephys.py0000644000175100001730000013111314467767506016250 0ustar00runnerdockerimport warnings from copy import copy import numpy as np from hdmf.common import DynamicTable, AlignedDynamicTable from hdmf.utils import docval, popargs, popargs_to_dict, get_docval, getargs from . import register_class, CORE_NAMESPACE from .base import TimeSeries, TimeSeriesReferenceVectorData from .core import NWBContainer from .device import Device def ensure_unit(self, name, current_unit, unit, nwb_version): """A helper to ensure correct unit used. Issues a warning with details if `current_unit` is to be ignored, and `unit` to be used instead. """ if current_unit != unit: warnings.warn( "Unit '%s' for %s '%s' is ignored and will be set to '%s' " "as per NWB %s." % (current_unit, self.__class__.__name__, name, unit, nwb_version)) return unit @register_class('IntracellularElectrode', CORE_NAMESPACE) class IntracellularElectrode(NWBContainer): """Describes an intracellular electrode and associated metadata.""" __nwbfields__ = ('cell_id', 'slice', 'seal', 'description', 'location', 'resistance', 'filtering', 'initial_access_resistance', 'device') @docval({'name': 'name', 'type': str, 'doc': 'the name of this electrode'}, {'name': 'device', 'type': Device, 'doc': 'the device that was used to record from this electrode'}, {'name': 'description', 'type': str, 'doc': 'Recording description, description of electrode (e.g., whole-cell, sharp, etc).'}, {'name': 'slice', 'type': str, 'doc': 'Information about slice used for recording.', 'default': None}, {'name': 'seal', 'type': str, 'doc': 'Information about seal used for recording.', 'default': None}, {'name': 'location', 'type': str, 'doc': 'Area, layer, comments on estimation, stereotaxis coordinates (if in vivo, etc).', 'default': None}, {'name': 'resistance', 'type': str, 'doc': 'Electrode resistance, unit: Ohm.', 'default': None}, {'name': 'filtering', 'type': str, 'doc': 'Electrode specific filtering.', 'default': None}, {'name': 'initial_access_resistance', 'type': str, 'doc': 'Initial access resistance.', 'default': None}, {'name': 'cell_id', 'type': str, 'doc': 'Unique ID of cell.', 'default': None} ) def __init__(self, **kwargs): keys_to_set = ( 'slice', 'seal', 'description', 'location', 'resistance', 'filtering', 'initial_access_resistance', 'device', 'cell_id' ) args_to_set = popargs_to_dict(keys_to_set, kwargs) super().__init__(**kwargs) for key, val in args_to_set.items(): setattr(self, key, val) @register_class('PatchClampSeries', CORE_NAMESPACE) class PatchClampSeries(TimeSeries): ''' Stores stimulus or response current or voltage. Superclass definition for patch-clamp data (this class should not be instantiated directly). ''' __nwbfields__ = ( 'electrode', 'gain', 'stimulus_description', 'sweep_number', ) @docval( *get_docval(TimeSeries.__init__, 'name'), # required { "name": "data", "type": ("array_data", "data", TimeSeries), "doc": "The data values. The first dimension must be time.", "shape": (None,), }, # required { 'name': 'unit', 'type': str, 'doc': 'The base unit of measurement (should be SI unit)', }, # required { 'name': 'electrode', 'type': IntracellularElectrode, 'doc': 'IntracellularElectrode group that describes the electrode that was ' 'used to apply or record this data.', }, # required { 'name': 'gain', 'type': float, 'doc': 'Units: Volt/Amp (v-clamp) or Volt/Volt (c-clamp)', }, # required { 'name': 'stimulus_description', 'type': str, 'doc': 'the stimulus name/protocol', 'default': "N/A", }, *get_docval( TimeSeries.__init__, 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'offset', ), { 'name': 'sweep_number', 'type': (int, 'uint32', 'uint64'), 'doc': 'Sweep number, allows for grouping different PatchClampSeries ' 'together via the sweep_table', 'default': None, } ) def __init__(self, **kwargs): name, data, unit, stimulus_description = popargs('name', 'data', 'unit', 'stimulus_description', kwargs) electrode, gain, sweep_number = popargs('electrode', 'gain', 'sweep_number', kwargs) super().__init__(name, data, unit, **kwargs) self.electrode = electrode self.gain = gain self.stimulus_description = stimulus_description if sweep_number is not None: if not (sweep_number >= 0): raise ValueError("sweep_number must be a non-negative integer") self.sweep_number = sweep_number @register_class('CurrentClampSeries', CORE_NAMESPACE) class CurrentClampSeries(PatchClampSeries): ''' Stores voltage data recorded from intracellular current-clamp recordings. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected. ''' __nwbfields__ = ('bias_current', 'bridge_balance', 'capacitance_compensation') @docval(*get_docval(PatchClampSeries.__init__, 'name', 'data', 'electrode'), # required {'name': 'gain', 'type': float, 'doc': 'Units: Volt/Volt'}, *get_docval(PatchClampSeries.__init__, 'stimulus_description'), {'name': 'bias_current', 'type': float, 'doc': 'Unit: Amp', 'default': None}, {'name': 'bridge_balance', 'type': float, 'doc': 'Unit: Ohm', 'default': None}, {'name': 'capacitance_compensation', 'type': float, 'doc': 'Unit: Farad', 'default': None}, *get_docval(PatchClampSeries.__init__, 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'sweep_number', 'offset'), {'name': 'unit', 'type': str, 'doc': "The base unit of measurement (must be 'volts')", 'default': 'volts'}) def __init__(self, **kwargs): name, data, unit, electrode, gain = popargs('name', 'data', 'unit', 'electrode', 'gain', kwargs) unit = ensure_unit(self, name, unit, 'volts', '2.1.0') bias_current, bridge_balance, capacitance_compensation = popargs( 'bias_current', 'bridge_balance', 'capacitance_compensation', kwargs) super().__init__(name, data, unit, electrode, gain, **kwargs) self.bias_current = bias_current self.bridge_balance = bridge_balance self.capacitance_compensation = capacitance_compensation @register_class('IZeroClampSeries', CORE_NAMESPACE) class IZeroClampSeries(CurrentClampSeries): ''' Stores recorded voltage data from intracellular recordings when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell. ''' __nwbfields__ = () @docval(*get_docval(CurrentClampSeries.__init__, 'name', 'data', 'electrode'), # required {'name': 'gain', 'type': float, 'doc': 'Units: Volt/Volt'}, # required {'name': 'stimulus_description', 'type': str, 'doc': ('The stimulus name/protocol. Setting this to a value other than "N/A" is deprecated as of ' 'NWB 2.3.0.'), 'default': 'N/A'}, *get_docval(CurrentClampSeries.__init__, 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'sweep_number', 'offset'), {'name': 'unit', 'type': str, 'doc': "The base unit of measurement (must be 'volts')", 'default': 'volts'}) def __init__(self, **kwargs): name, data, electrode, gain = popargs('name', 'data', 'electrode', 'gain', kwargs) bias_current, bridge_balance, capacitance_compensation = (0.0, 0.0, 0.0) stimulus_description = popargs('stimulus_description', kwargs) stimulus_description = self._ensure_stimulus_description(name, stimulus_description, 'N/A', '2.3.0') kwargs['stimulus_description'] = stimulus_description super().__init__(name, data, electrode, gain, bias_current, bridge_balance, capacitance_compensation, **kwargs) def _ensure_stimulus_description(self, name, current_stim_desc, stim_desc, nwb_version): """A helper to ensure correct stimulus_description used. Issues a warning with details if `current_stim_desc` is to be ignored, and `stim_desc` to be used instead. """ if current_stim_desc != stim_desc: warnings.warn( "Stimulus description '%s' for %s '%s' is ignored and will be set to '%s' " "as per NWB %s." % (current_stim_desc, self.__class__.__name__, name, stim_desc, nwb_version)) return stim_desc @register_class('CurrentClampStimulusSeries', CORE_NAMESPACE) class CurrentClampStimulusSeries(PatchClampSeries): ''' Alias to standard PatchClampSeries. Its functionality is to better tag PatchClampSeries for machine (and human) readability of the file. ''' __nwbfields__ = () @docval(*get_docval(PatchClampSeries.__init__, 'name', 'data', 'electrode', 'gain'), # required *get_docval(PatchClampSeries.__init__, 'stimulus_description', 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'sweep_number', 'offset'), {'name': 'unit', 'type': str, 'doc': "The base unit of measurement (must be 'amperes')", 'default': 'amperes'}) def __init__(self, **kwargs): name, data, unit, electrode, gain = popargs('name', 'data', 'unit', 'electrode', 'gain', kwargs) unit = ensure_unit(self, name, unit, 'amperes', '2.1.0') super().__init__(name, data, unit, electrode, gain, **kwargs) @register_class('VoltageClampSeries', CORE_NAMESPACE) class VoltageClampSeries(PatchClampSeries): ''' Stores current data recorded from intracellular voltage-clamp recordings. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected. ''' __nwbfields__ = ('capacitance_fast', 'capacitance_slow', 'resistance_comp_bandwidth', 'resistance_comp_correction', 'resistance_comp_prediction', 'whole_cell_capacitance_comp', 'whole_cell_series_resistance_comp') @docval(*get_docval(PatchClampSeries.__init__, 'name', 'data', 'electrode'), # required {'name': 'gain', 'type': float, 'doc': 'Units: Volt/Amp'}, # required *get_docval(PatchClampSeries.__init__, 'stimulus_description'), {'name': 'capacitance_fast', 'type': float, 'doc': 'Unit: Farad', 'default': None}, {'name': 'capacitance_slow', 'type': float, 'doc': 'Unit: Farad', 'default': None}, {'name': 'resistance_comp_bandwidth', 'type': float, 'doc': 'Unit: Hz', 'default': None}, {'name': 'resistance_comp_correction', 'type': float, 'doc': 'Unit: percent', 'default': None}, {'name': 'resistance_comp_prediction', 'type': float, 'doc': 'Unit: percent', 'default': None}, {'name': 'whole_cell_capacitance_comp', 'type': float, 'doc': 'Unit: Farad', 'default': None}, {'name': 'whole_cell_series_resistance_comp', 'type': float, 'doc': 'Unit: Ohm', 'default': None}, *get_docval(PatchClampSeries.__init__, 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'sweep_number', 'offset'), {'name': 'unit', 'type': str, 'doc': "The base unit of measurement (must be 'amperes')", 'default': 'amperes'}) def __init__(self, **kwargs): name, data, unit, electrode, gain = popargs('name', 'data', 'unit', 'electrode', 'gain', kwargs) unit = ensure_unit(self, name, unit, 'amperes', '2.1.0') capacitance_fast, capacitance_slow, resistance_comp_bandwidth, resistance_comp_correction, \ resistance_comp_prediction, whole_cell_capacitance_comp, whole_cell_series_resistance_comp = popargs( 'capacitance_fast', 'capacitance_slow', 'resistance_comp_bandwidth', 'resistance_comp_correction', 'resistance_comp_prediction', 'whole_cell_capacitance_comp', 'whole_cell_series_resistance_comp', kwargs) super().__init__(name, data, unit, electrode, gain, **kwargs) self.capacitance_fast = capacitance_fast self.capacitance_slow = capacitance_slow self.resistance_comp_bandwidth = resistance_comp_bandwidth self.resistance_comp_correction = resistance_comp_correction self.resistance_comp_prediction = resistance_comp_prediction self.whole_cell_capacitance_comp = whole_cell_capacitance_comp self.whole_cell_series_resistance_comp = whole_cell_series_resistance_comp @register_class('VoltageClampStimulusSeries', CORE_NAMESPACE) class VoltageClampStimulusSeries(PatchClampSeries): ''' Alias to standard PatchClampSeries. Its functionality is to better tag PatchClampSeries for machine (and human) readability of the file. ''' __nwbfields__ = () @docval(*get_docval(PatchClampSeries.__init__, 'name', 'data', 'electrode', 'gain'), # required *get_docval(PatchClampSeries.__init__, 'stimulus_description', 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'sweep_number', 'offset'), {'name': 'unit', 'type': str, 'doc': "The base unit of measurement (must be 'volts')", 'default': 'volts'}) def __init__(self, **kwargs): name, data, unit, electrode, gain = popargs('name', 'data', 'unit', 'electrode', 'gain', kwargs) unit = ensure_unit(self, name, unit, 'volts', '2.1.0') super().__init__(name, data, unit, electrode, gain, **kwargs) @register_class('SweepTable', CORE_NAMESPACE) class SweepTable(DynamicTable): """ A SweepTable allows to group PatchClampSeries together which stem from the same sweep. A sweep is a group of PatchClampSeries which have the same starting point in time. """ __columns__ = ( {'name': 'series', 'description': 'PatchClampSeries with the same sweep number', 'required': True, 'index': True}, {'name': 'sweep_number', 'description': 'Sweep number of the entries in that row', 'required': True} ) @docval({'name': 'name', 'type': str, 'doc': 'name of this SweepTable', 'default': 'sweep_table'}, {'name': 'description', 'type': str, 'doc': 'Description of this SweepTable', 'default': "A sweep table groups different PatchClampSeries together."}, *get_docval(DynamicTable.__init__, 'id', 'columns', 'colnames')) def __init__(self, **kwargs): warnings.warn("Use of SweepTable is deprecated. Use the IntracellularRecordingsTable " "instead. See also the NWBFile.add_intracellular_recordings function.", DeprecationWarning) super().__init__(**kwargs) @docval({'name': 'pcs', 'type': PatchClampSeries, 'doc': 'PatchClampSeries to add to the table must have a valid sweep_number'}) def add_entry(self, pcs): """ Add the passed PatchClampSeries to the sweep table. """ kwargs = {'sweep_number': pcs.sweep_number, 'series': [pcs]} # FIXME appending to an existing entry would be nicer # but this seems to be not possible self.add_row(**kwargs) def get_series(self, sweep_number): """ Return a list of PatchClampSeries for the given sweep number. """ ids = self.__get_row_ids(sweep_number) if len(ids) == 0: return None matches = [] for x in ids: for y in self[(x, 'series')]: matches.append(y) return matches def __get_row_ids(self, sweep_number): """ Return the row ids for the given sweep number. """ return [index for index, elem in enumerate(self['sweep_number'].data) if elem == sweep_number] @register_class('IntracellularElectrodesTable', CORE_NAMESPACE) class IntracellularElectrodesTable(DynamicTable): """ Table for storing intracellular electrode related metadata' """ __columns__ = ( {'name': 'electrode', 'description': 'Column for storing the reference to the intracellular electrode', 'required': True, 'index': False, 'table': False}, ) @docval(*get_docval(DynamicTable.__init__, 'id', 'columns', 'colnames')) def __init__(self, **kwargs): # Define defaultb name and description settings kwargs['name'] = 'electrodes' kwargs['description'] = ('Table for storing intracellular electrode related metadata') # Initialize the DynamicTable super().__init__(**kwargs) @register_class('IntracellularStimuliTable', CORE_NAMESPACE) class IntracellularStimuliTable(DynamicTable): """ Table for storing intracellular electrode related metadata' """ __columns__ = ( {'name': 'stimulus', 'description': 'Column storing the reference to the recorded stimulus for the recording (rows)', 'required': True, 'index': False, 'table': False, 'class': TimeSeriesReferenceVectorData}, ) @docval(*get_docval(DynamicTable.__init__, 'id', 'columns', 'colnames')) def __init__(self, **kwargs): # Define defaultb name and description settings kwargs['name'] = 'stimuli' kwargs['description'] = ('Table for storing intracellular stimulus related metadata') # Initialize the DynamicTable super().__init__(**kwargs) @register_class('IntracellularResponsesTable', CORE_NAMESPACE) class IntracellularResponsesTable(DynamicTable): """ Table for storing intracellular electrode related metadata' """ __columns__ = ( {'name': 'response', 'description': 'Column storing the reference to the recorded response for the recording (rows)', 'required': True, 'index': False, 'table': False, 'class': TimeSeriesReferenceVectorData}, ) @docval(*get_docval(DynamicTable.__init__, 'id', 'columns', 'colnames')) def __init__(self, **kwargs): # Define defaultb name and description settings kwargs['name'] = 'responses' kwargs['description'] = ('Table for storing intracellular response related metadata') # Initialize the DynamicTable super().__init__(**kwargs) @register_class('IntracellularRecordingsTable', CORE_NAMESPACE) class IntracellularRecordingsTable(AlignedDynamicTable): """ A table to group together a stimulus and response from a single electrode and a single simultaneous_recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. """ @docval(*get_docval(AlignedDynamicTable.__init__, 'id', 'columns', 'colnames', 'category_tables', 'categories')) def __init__(self, **kwargs): kwargs['name'] = 'intracellular_recordings' kwargs['description'] = ('A table to group together a stimulus and response from a single electrode ' 'and a single simultaneous recording and for storing metadata about the ' 'intracellular recording.') in_category_tables = getargs('category_tables', kwargs) if in_category_tables is None or len(in_category_tables) == 0: kwargs['category_tables'] = [IntracellularElectrodesTable(), IntracellularStimuliTable(), IntracellularResponsesTable()] kwargs['categories'] = None else: # Check if our required data tables are supplied, otherwise add them to the list required_dynamic_table_given = [-1 for i in range(3)] # The first three are our required tables for i, tab in enumerate(in_category_tables): if isinstance(tab, IntracellularElectrodesTable): required_dynamic_table_given[0] = i elif isinstance(tab, IntracellularStimuliTable): required_dynamic_table_given[1] = i elif isinstance(tab, IntracellularResponsesTable): required_dynamic_table_given[2] = i # Check if the supplied tables contain data but not all required tables have been supplied required_dynamic_table_missing = np.any(np.array(required_dynamic_table_given[0:3]) < 0) if len(in_category_tables[0]) != 0 and required_dynamic_table_missing: raise ValueError("IntracellularElectrodeTable, IntracellularStimuliTable, and " "IntracellularResponsesTable are required when adding custom, non-empty " "tables to IntracellularRecordingsTable as the missing data for the required " "tables cannot be determined automatically") # Compile the complete list of tables dynamic_table_arg = copy(in_category_tables) categories_arg = [] if getargs('categories', kwargs) is None else copy(getargs('categories', kwargs)) if required_dynamic_table_missing: if required_dynamic_table_given[2] < 0: dynamic_table_arg.append(IntracellularResponsesTable) if not dynamic_table_arg[-1].name in categories_arg: categories_arg.insert(0, dynamic_table_arg[-1].name) if required_dynamic_table_given[1] < 0: dynamic_table_arg.append(IntracellularStimuliTable()) if not dynamic_table_arg[-1].name in categories_arg: categories_arg.insert(0, dynamic_table_arg[-1].name) if required_dynamic_table_given[0] < 0: dynamic_table_arg.append(IntracellularElectrodesTable()) if not dynamic_table_arg[-1].name in categories_arg: categories_arg.insert(0, dynamic_table_arg[-1].name) kwargs['category_tables'] = dynamic_table_arg kwargs['categories'] = categories_arg super().__init__(**kwargs) @docval( { "name": "electrode", "type": IntracellularElectrode, "doc": "The intracellular electrode used", "default": None, }, {'name': 'stimulus_start_index', 'type': int, 'doc': 'Start index of the stimulus', 'default': None}, {'name': 'stimulus_index_count', 'type': int, 'doc': 'Stop index of the stimulus', 'default': None}, {'name': 'stimulus', 'type': TimeSeries, 'doc': 'The TimeSeries (usually a PatchClampSeries) with the stimulus', 'default': None}, {'name': 'response_start_index', 'type': int, 'doc': 'Start index of the response', 'default': None}, {'name': 'response_index_count', 'type': int, 'doc': 'Stop index of the response', 'default': None}, {'name': 'response', 'type': TimeSeries, 'doc': 'The TimeSeries (usually a PatchClampSeries) with the response', 'default': None}, {'name': 'electrode_metadata', 'type': dict, 'doc': 'Additional electrode metadata to be stored in the electrodes table', 'default': None}, {'name': 'stimulus_metadata', 'type': dict, 'doc': 'Additional stimulus metadata to be stored in the stimuli table', 'default': None}, {'name': 'response_metadata', 'type': dict, 'doc': 'Additional resposnse metadata to be stored in the responses table', 'default': None}, returns='Integer index of the row that was added to this table', rtype=int, allow_extra=True, ) def add_recording(self, **kwargs): """ Add a single recording to the IntracellularRecordingsTable table. Typically, both stimulus and response are expected. However, in some cases only a stimulus or a response may be recodred as part of a recording. In this case, None may be given for either stimulus or response, but not both. Internally, this results in both stimulus and response pointing to the same TimeSeries, while the start_index and index_count for the invalid series will both be set to -1. """ # Get the input data stimulus_start_index, stimulus_index_count, stimulus = popargs('stimulus_start_index', 'stimulus_index_count', 'stimulus', kwargs) response_start_index, response_index_count, response = popargs('response_start_index', 'response_index_count', 'response', kwargs) electrode = popargs('electrode', kwargs) # if electrode is not provided, take from stimulus or response object if electrode is None: if stimulus: electrode = stimulus.electrode elif response: electrode = response.electrode # Confirm that we have at least a valid stimulus or response if stimulus is None and response is None: raise ValueError("stimulus and response cannot both be None.") # Compute the start and stop index if necessary stimulus_start_index, stimulus_index_count = self.__compute_index(stimulus_start_index, stimulus_index_count, stimulus, 'stimulus') response_start_index, response_index_count = self.__compute_index(response_start_index, response_index_count, response, 'response') # If either stimulus or response are None, then set them to the same TimeSeries to keep the I/O happy response = response if response is not None else stimulus stimulus_provided_is_not_none = stimulus is not None # Store if stimulus is None for error checks later stimulus = stimulus if stimulus_provided_is_not_none else response # Make sure the types are compatible. if ((response.neurodata_type.startswith("CurrentClamp") and stimulus.neurodata_type.startswith("VoltageClamp")) or (response.neurodata_type.startswith("VoltageClamp") and stimulus.neurodata_type.startswith("CurrentClamp"))): raise ValueError("Incompatible types given for 'stimulus' and 'response' parameters. " "'stimulus' is of type %s and 'response' is of type %s." % (stimulus.neurodata_type, response.neurodata_type)) if response.neurodata_type == 'IZeroClampSeries': if stimulus_provided_is_not_none: raise ValueError("stimulus should usually be None for IZeroClampSeries response") if isinstance(response, PatchClampSeries) and isinstance(stimulus, PatchClampSeries): # # We could also check sweep_number, but since it is mostly relevant to the deprecated SweepTable # # we don't really need to enforce it here # if response.sweep_number != stimulus.sweep_number: # warnings.warn("sweep_number are usually expected to be the same for PatchClampSeries type " # "stimulus and response pairs in an intracellular recording.") if response.electrode != stimulus.electrode: raise ValueError( "electrodes are usually expected to be the same for PatchClampSeries type stimulus and response " "pairs in an intracellular recording." ) # Compile the electrodes table data electrodes = copy(popargs('electrode_metadata', kwargs)) if electrodes is None: electrodes = {} electrodes['electrode'] = electrode # Compile the stimuli table data stimuli = copy(popargs('stimulus_metadata', kwargs)) if stimuli is None: stimuli = {} stimuli['stimulus'] = TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE( stimulus_start_index, stimulus_index_count, stimulus) # Compile the responses table data responses = copy(popargs('response_metadata', kwargs)) if responses is None: responses = {} responses['response'] = TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE( response_start_index, response_index_count, response) _ = super().add_row(enforce_unique_id=True, electrodes=electrodes, responses=responses, stimuli=stimuli, **kwargs) return len(self) - 1 @staticmethod def __compute_index(start_index, index_count, time_series, name): """ Internal helper function to compute the start_index and index_count to use for the stimulus and response column :param start_index: The start_index provided by the user :param index_count: The index count provided by the user :param time_series: The timeseries object to reference. May be None. :param name: Name of the table. Used only to enhance error reporting :raises IndexError: If index_count cannot be determined or start_index+index_count are outside of the range of the timeseries. :returns: A tuple of integers with the start_index and index_count to use. """ # If times_series is not valid then return -1, -1 to indicate invalid times if time_series is None: return -1, -1 # Since time_series is valid, negative or None start_index means the user did not specify a start_index # so we now need to set it to 0 if start_index is None or start_index < 0: start_index = 0 # If index_count has not been set yet (i.e., it is -1 or None) then attempt to set it to the # full range of the timeseries starting from start_index num_samples = time_series.num_samples if index_count is None or index_count < 0: index_count = (num_samples - start_index) if num_samples is not None else None # Check that the start_index and index_count are valid and raise IndexError if they are invalid if index_count is None: raise IndexError("Invalid %s_index_count cannot be determined from %s data." % (name, name)) if num_samples is not None: if start_index >= num_samples: raise IndexError("%s_start_index out of range" % name) if (start_index + index_count) > num_samples: raise IndexError("%s_start_index + %s_index_count out of range" % (name, name)) # Return the values return start_index, index_count @docval(*get_docval(AlignedDynamicTable.to_dataframe, 'ignore_category_ids'), {'name': 'electrode_refs_as_objectids', 'type': bool, 'doc': 'replace object references in the electrode column with object_ids', 'default': False}, {'name': 'stimulus_refs_as_objectids', 'type': bool, 'doc': 'replace object references in the stimulus column with object_ids', 'default': False}, {'name': 'response_refs_as_objectids', 'type': bool, 'doc': 'replace object references in the response column with object_ids', 'default': False} ) def to_dataframe(self, **kwargs): """Convert the collection of tables to a single pandas DataFrame""" res = super().to_dataframe(ignore_category_ids=getargs('ignore_category_ids', kwargs)) if getargs('electrode_refs_as_objectids', kwargs): res[('electrodes', 'electrode')] = [e.object_id for e in res[('electrodes', 'electrode')]] if getargs('stimulus_refs_as_objectids', kwargs): res[('stimuli', 'stimulus')] = \ [e if e[2] is None else TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE(e[0], e[1], e[2].object_id) for e in res[('stimuli', 'stimulus')]] if getargs('response_refs_as_objectids', kwargs): res[('responses', 'response')] = \ [e if e[2] is None else TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE(e[0], e[1], e[2].object_id) for e in res[('responses', 'response')]] return res @register_class('SimultaneousRecordingsTable', CORE_NAMESPACE) class SimultaneousRecordingsTable(DynamicTable): """ A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes. """ __columns__ = ( {'name': 'recordings', 'description': 'Column with references to one or more rows in the IntracellularRecordingsTable table', 'required': True, 'index': True, 'table': True}, ) @docval({'name': 'intracellular_recordings_table', 'type': IntracellularRecordingsTable, 'doc': 'the IntracellularRecordingsTable table that the recordings column indexes. May be None when ' 'reading the Container from file as the table attribute is already populated in this case ' 'but otherwise this is required.', 'default': None}, *get_docval(DynamicTable.__init__, 'id', 'columns', 'colnames')) def __init__(self, **kwargs): intracellular_recordings_table = popargs('intracellular_recordings_table', kwargs) # Define default name and description settings kwargs['name'] = 'simultaneous_recordings' kwargs['description'] = ('A table for grouping different intracellular recordings from the' 'IntracellularRecordingsTable table together that were recorded simultaneously ' 'from different electrodes.') # Initialize the DynamicTable super().__init__(**kwargs) if self['recordings'].target.table is None: if intracellular_recordings_table is not None: self['recordings'].target.table = intracellular_recordings_table else: raise ValueError("intracellular_recordings constructor argument required") @docval({'name': 'recordings', 'type': 'array_data', 'doc': 'the indices of the recordings belonging to this simultaneous recording'}, returns='Integer index of the row that was added to this table', rtype=int, allow_extra=True) def add_simultaneous_recording(self, **kwargs): """ Add a single simultaneous recording (i.e., one sweep, or one row) consisting of one or more recordings and associated custom simultaneous recording metadata to the table. """ _ = super().add_row(enforce_unique_id=True, **kwargs) return len(self.id) - 1 @register_class('SequentialRecordingsTable', CORE_NAMESPACE) class SequentialRecordingsTable(DynamicTable): """ A table for grouping different intracellular recording simultaneous_recordings from the SimultaneousRecordingsTable table together. This is typically used to group together simultaneous_recordings where the a sequence of stimuli of the same type with varying parameters have been presented in a sequence. """ __columns__ = ( {'name': 'simultaneous_recordings', 'description': 'Column with references to one or more rows in the SimultaneousRecordingsTable table', 'required': True, 'index': True, 'table': True}, {'name': 'stimulus_type', 'description': 'Column storing the type of stimulus used for the sequential recording', 'required': True, 'index': False, 'table': False} ) @docval({'name': 'simultaneous_recordings_table', 'type': SimultaneousRecordingsTable, 'doc': 'the SimultaneousRecordingsTable table that the simultaneous_recordings ' 'column indexes. May be None when reading the Container from file as the ' 'table attribute is already populated in this case but otherwise this is required.', 'default': None}, *get_docval(DynamicTable.__init__, 'id', 'columns', 'colnames')) def __init__(self, **kwargs): simultaneous_recordings_table = popargs('simultaneous_recordings_table', kwargs) # Define defaultb name and description settings kwargs['name'] = 'sequential_recordings' kwargs['description'] = ('A table for grouping different intracellular recording simultaneous_recordings ' 'from the SimultaneousRecordingsTable table together. This is typically used to ' 'group together simultaneous_recordings where the a sequence of stimuli of the ' 'same type with varying parameters have been presented in a sequence.') # Initialize the DynamicTable super().__init__(**kwargs) if self['simultaneous_recordings'].target.table is None: if simultaneous_recordings_table is not None: self['simultaneous_recordings'].target.table = simultaneous_recordings_table else: raise ValueError('simultaneous_recordings_table constructor argument required') @docval({'name': 'stimulus_type', 'type': str, 'doc': 'the type of stimulus used for the sequential recording'}, {'name': 'simultaneous_recordings', 'type': 'array_data', 'doc': 'the indices of the simultaneous_recordings belonging to this sequential recording'}, returns='Integer index of the row that was added to this table', rtype=int, allow_extra=True) def add_sequential_recording(self, **kwargs): """ Add a sequential recording (i.e., one row) consisting of one or more simultaneous recordings and associated custom sequential recording metadata to the table. """ _ = super().add_row(enforce_unique_id=True, **kwargs) return len(self.id) - 1 @register_class('RepetitionsTable', CORE_NAMESPACE) class RepetitionsTable(DynamicTable): """ A table for grouping different intracellular recording sequential recordings together. With each SweepSequence typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence. """ __columns__ = ( {'name': 'sequential_recordings', 'description': 'Column with references to one or more rows in the SequentialRecordingsTable table', 'required': True, 'index': True, 'table': True}, ) @docval({'name': 'sequential_recordings_table', 'type': SequentialRecordingsTable, 'doc': 'the SequentialRecordingsTable table that the sequential_recordings column indexes. May ' 'be None when reading the Container from file as the table attribute is already populated ' 'in this case but otherwise this is required.', 'default': None}, *get_docval(DynamicTable.__init__, 'id', 'columns', 'colnames')) def __init__(self, **kwargs): sequential_recordings_table = popargs('sequential_recordings_table', kwargs) # Define default name and description settings kwargs['name'] = 'repetitions' kwargs['description'] = ('A table for grouping different intracellular recording sequential recordings ' 'together. With each SimultaneousRecording typically representing a particular type ' 'of stimulus, the RepetitionsTable table is typically used to group sets ' 'of stimuli applied in sequence.') # Initialize the DynamicTable super().__init__(**kwargs) if self['sequential_recordings'].target.table is None: if sequential_recordings_table is not None: self['sequential_recordings'].target.table = sequential_recordings_table else: raise ValueError('sequential_recordings_table constructor argument required') @docval({'name': 'sequential_recordings', 'type': 'array_data', 'doc': 'the indices of the sequential recordings belonging to this repetition', 'default': None}, returns='Integer index of the row that was added to this table', rtype=int, allow_extra=True) def add_repetition(self, **kwargs): """ Add a repetition (i.e., one row) consisting of one or more sequential recordings and associated custom repetition metadata to the table. """ _ = super().add_row(enforce_unique_id=True, **kwargs) return len(self.id) - 1 @register_class('ExperimentalConditionsTable', CORE_NAMESPACE) class ExperimentalConditionsTable(DynamicTable): """ A table for grouping different intracellular recording repetitions together that belong to the same experimental conditions. """ __columns__ = ( {'name': 'repetitions', 'description': 'Column with references to one or more rows in the RepetitionsTable table', 'required': True, 'index': True, 'table': True}, ) @docval({'name': 'repetitions_table', 'type': RepetitionsTable, 'doc': 'the RepetitionsTable table that the repetitions column indexes', 'default': None}, *get_docval(DynamicTable.__init__, 'id', 'columns', 'colnames')) def __init__(self, **kwargs): repetitions_table = popargs('repetitions_table', kwargs) # Define default name and description settings kwargs['name'] = 'experimental_conditions' kwargs['description'] = ('A table for grouping different intracellular recording repetitions together that ' 'belong to the same experimental conditions.') # Initialize the DynamicTable super().__init__(**kwargs) if self['repetitions'].target.table is None: if repetitions_table is not None: self['repetitions'].target.table = repetitions_table else: raise ValueError('repetitions_table constructor argument required') @docval({'name': 'repetitions', 'type': 'array_data', 'doc': 'the indices of the repetitions belonging to this condition', 'default': None}, returns='Integer index of the row that was added to this table', rtype=int, allow_extra=True) def add_experimental_condition(self, **kwargs): """ Add a condition (i.e., one row) consisting of one or more repetitions of sequential recordings and associated custom experimental_conditions metadata to the table. """ _ = super().add_row(enforce_unique_id=True, **kwargs) return len(self.id) - 1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/image.py0000644000175100001730000004251414467767506015674 0ustar00runnerdockerimport warnings from collections.abc import Iterable import numpy as np from hdmf.utils import ( docval, getargs, popargs, popargs_to_dict, get_docval, get_data_shape, ) from . import register_class, CORE_NAMESPACE from .base import TimeSeries, Image, Images from .device import Device @register_class('ImageSeries', CORE_NAMESPACE) class ImageSeries(TimeSeries): ''' General image data that is common between acquisition and stimulus time series. The image data can be stored in the HDF5 file or it will be stored as an external image file. ''' __nwbfields__ = ('dimension', 'external_file', 'starting_frame', 'format', 'device') # value used when an ImageSeries is read and missing data DEFAULT_DATA = np.ndarray(shape=(0, 0, 0), dtype=np.uint8) # TODO: copy new docs from 2.4 schema @docval(*get_docval(TimeSeries.__init__, 'name'), # required {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': ([None] * 3, [None] * 4), 'doc': ('The data values. Can be 3D or 4D. The first dimension must be time (frame). The second and third ' 'dimensions represent x and y. The optional fourth dimension represents z. Either data or ' 'external_file must be specified (not None), but not both. If data is not specified, ' 'data will be set to an empty 3D array.'), 'default': None}, {'name': 'unit', 'type': str, 'doc': ('The unit of measurement of the image data, e.g., values between 0 and 255. Required when data ' 'is specified. If unit (and data) are not specified, then unit will be set to "unknown".'), 'default': None}, {'name': 'format', 'type': str, 'doc': 'Format of image. Three types: 1) Image format; tiff, png, jpg, etc. 2) external 3) raw.', 'default': None}, {'name': 'external_file', 'type': ('array_data', 'data'), 'doc': 'Path or URL to one or more external file(s). Field only present if format=external. ' 'Either external_file or data must be specified (not None), but not both.', 'default': None}, {'name': 'starting_frame', 'type': Iterable, 'doc': 'Each entry is a frame number that corresponds to the first frame of each file ' 'listed in external_file within the full ImageSeries.', 'default': None}, {'name': 'bits_per_pixel', 'type': int, 'doc': 'DEPRECATED: Number of bits per image pixel', 'default': None}, {'name': 'dimension', 'type': Iterable, 'doc': 'Number of pixels on x, y, (and z) axes.', 'default': None}, *get_docval(TimeSeries.__init__, 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'offset'), {'name': 'device', 'type': Device, 'doc': 'Device used to capture the images/video.', 'default': None},) def __init__(self, **kwargs): keys_to_set = ('bits_per_pixel', 'dimension', 'external_file', 'starting_frame', 'format', 'device') args_to_set = popargs_to_dict(keys_to_set, kwargs) name, data, unit = getargs('name', 'data', 'unit', kwargs) if data is not None and unit is None: raise ValueError("Must supply 'unit' argument when supplying 'data' to %s '%s'." % (self.__class__.__name__, name)) if args_to_set['external_file'] is None and data is None: raise ValueError("Must supply either external_file or data to %s '%s'." % (self.__class__.__name__, name)) # data and unit are required in TimeSeries, but allowed to be None here, so handle this specially if data is None: kwargs['data'] = ImageSeries.DEFAULT_DATA if unit is None: kwargs['unit'] = ImageSeries.DEFAULT_UNIT # If a single external_file is given then set starting_frame to [0] for backward compatibility if ( args_to_set["external_file"] is not None and args_to_set["starting_frame"] is None ): args_to_set["starting_frame"] = ( [0] if len(args_to_set["external_file"]) == 1 else None ) super().__init__(**kwargs) for key, val in args_to_set.items(): setattr(self, key, val) if self._change_external_file_format(): warnings.warn( "%s '%s': The value for 'format' has been changed to 'external'. " "Setting a default value for 'format' is deprecated and will be changed " "to raising a ValueError in the next major release." % (self.__class__.__name__, self.name), DeprecationWarning, ) if not self._check_image_series_dimension(): warnings.warn( "%s '%s': Length of data does not match length of timestamps. Your data may be transposed. " "Time should be on the 0th dimension" % (self.__class__.__name__, self.name) ) self._error_on_new_warn_on_construct( error_msg=self._check_external_file_starting_frame_length() ) self._error_on_new_warn_on_construct( error_msg=self._check_external_file_format() ) self._error_on_new_warn_on_construct(error_msg=self._check_external_file_data()) def _change_external_file_format(self): """ Change the format to 'external' when external_file is specified. """ if ( get_data_shape(self.data)[0] == 0 and self.external_file is not None and self.format is None ): self.format = "external" return True return False def _check_time_series_dimension(self): """Override _check_time_series_dimension to do nothing. The _check_image_series_dimension method will be called instead. """ return True def _check_image_series_dimension(self): """Check that the 0th dimension of data equals the length of timestamps, when applicable. ImageSeries objects can have an external file instead of data stored. The external file cannot be queried for the number of frames it contains, so this check will return True when an external file is provided. Otherwise, this function calls the parent class' _check_time_series_dimension method. """ if self.external_file is not None: return True return super()._check_time_series_dimension() def _check_external_file_starting_frame_length(self): """ Check that the number of frame indices in 'starting_frame' matches the number of files in 'external_file'. """ if self.external_file is None: return if get_data_shape(self.external_file) == get_data_shape(self.starting_frame): return return ( "%s '%s': The number of frame indices in 'starting_frame' should have " "the same length as 'external_file'." % (self.__class__.__name__, self.name) ) def _check_external_file_format(self): """ Check that format is 'external' when external_file is specified. """ if self.external_file is None: return if self.format == "external": return return "%s '%s': Format must be 'external' when external_file is specified." % ( self.__class__.__name__, self.name, ) def _check_external_file_data(self): """ Check that data is an empty array when external_file is specified. """ if self.external_file is None: return if get_data_shape(self.data)[0] == 0: return return ( "%s '%s': Either external_file or data must be specified (not None), but not both." % (self.__class__.__name__, self.name) ) @property def bits_per_pixel(self): return self.fields.get('bits_per_pixel') @bits_per_pixel.setter def bits_per_pixel(self, val): if val is not None: warnings.warn("bits_per_pixel is no longer used", DeprecationWarning) self.fields['bits_per_pixel'] = val @register_class('IndexSeries', CORE_NAMESPACE) class IndexSeries(TimeSeries): ''' Stores indices to image frames stored in an ImageSeries. The purpose of the IndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed. ''' __nwbfields__ = ("indexed_timeseries",) # # value used when an ImageSeries is read and missing data # DEFAULT_UNIT = 'N/A' @docval( *get_docval(TimeSeries.__init__, 'name'), # required { 'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': (None,), # required 'doc': 'The data values. Must be 1D, where the first dimension must be time (frame)', }, *get_docval(TimeSeries.__init__, 'unit'), # required { 'name': 'indexed_timeseries', 'type': TimeSeries, # required 'doc': 'Link to TimeSeries containing images that are indexed.', 'default': None, }, { 'name': 'indexed_images', 'type': Images, # required 'doc': "Link to Images object containing an ordered set of images that are indexed. The Images object must " "contain a 'ordered_images' dataset specifying the order of the images in the Images type.", 'default': None }, *get_docval( TimeSeries.__init__, 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'offset', ), ) def __init__(self, **kwargs): indexed_timeseries, indexed_images = popargs('indexed_timeseries', 'indexed_images', kwargs) if kwargs['unit'] and kwargs['unit'] != 'N/A': msg = ("The 'unit' field of IndexSeries is fixed to the value 'N/A' starting in NWB 2.5. Passing " "a different value for 'unit' will raise an error in PyNWB 3.0.") warnings.warn(msg, PendingDeprecationWarning) if not indexed_timeseries and not indexed_images: msg = "Either indexed_timeseries or indexed_images must be provided when creating an IndexSeries." raise ValueError(msg) if indexed_timeseries: msg = ("The indexed_timeseries field of IndexSeries is discouraged and will be deprecated in " "a future version of NWB. Use the indexed_images field instead.") warnings.warn(msg, PendingDeprecationWarning) kwargs['unit'] = 'N/A' # fixed value starting in NWB 2.5 super().__init__(**kwargs) self.indexed_timeseries = indexed_timeseries self.indexed_images = indexed_images if kwargs['conversion'] and kwargs['conversion'] != self.DEFAULT_CONVERSION: warnings.warn("The conversion attribute is not used by IndexSeries.") if kwargs['resolution'] and kwargs['resolution'] != self.DEFAULT_RESOLUTION: warnings.warn("The resolution attribute is not used by IndexSeries.") if kwargs['offset'] and kwargs['offset'] != self.DEFAULT_OFFSET: warnings.warn("The offset attribute is not used by IndexSeries.") @register_class('ImageMaskSeries', CORE_NAMESPACE) class ImageMaskSeries(ImageSeries): ''' An alpha mask that is applied to a presented visual stimulus. The data[] array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed. ''' __nwbfields__ = ('masked_imageseries',) @docval(*get_docval(ImageSeries.__init__, 'name'), # required {'name': 'masked_imageseries', 'type': ImageSeries, # required 'doc': 'Link to ImageSeries that mask is applied to.'}, *get_docval(ImageSeries.__init__, 'data', 'unit', 'format', 'external_file', 'starting_frame', 'bits_per_pixel', 'dimension', 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'offset'), {'name': 'device', 'type': Device, 'doc': ('Device used to capture the mask data. This field will likely not be needed. ' 'The device used to capture the masked ImageSeries data should be stored in the ImageSeries.'), 'default': None},) def __init__(self, **kwargs): masked_imageseries = popargs('masked_imageseries', kwargs) super().__init__(**kwargs) self.masked_imageseries = masked_imageseries @register_class('OpticalSeries', CORE_NAMESPACE) class OpticalSeries(ImageSeries): ''' Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (eg, how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important. ''' __nwbfields__ = ('distance', 'field_of_view', 'orientation') @docval(*get_docval(ImageSeries.__init__, 'name'), # required {'name': 'distance', 'type': float, 'doc': 'Distance from camera/monitor to target/eye.'}, # required {'name': 'field_of_view', 'type': ('array_data', 'data', 'TimeSeries'), 'shape': ((2, ), (3, )), # required 'doc': 'Width, height and depth of image, or imaged area (meters).'}, {'name': 'orientation', 'type': str, # required 'doc': 'Description of image relative to some reference frame (e.g., which way is up). ' 'Must also specify frame of reference.'}, {'name': 'data', 'type': ('array_data', 'data'), 'shape': ([None] * 3, [None, None, None, 3]), 'doc': ('Images presented to subject, either grayscale or RGB. May be 3D or 4D. The first dimension must ' 'be time (frame). The second and third dimensions represent x and y. The optional fourth ' 'dimension must be length 3 and represents the RGB value for color images. Either data or ' 'external_file must be specified, but not both.'), 'default': None}, *get_docval(ImageSeries.__init__, 'unit', 'format', 'external_file', 'starting_frame', 'bits_per_pixel', 'dimension', 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'device', 'offset')) def __init__(self, **kwargs): distance, field_of_view, orientation = popargs('distance', 'field_of_view', 'orientation', kwargs) super().__init__(**kwargs) self.distance = distance self.field_of_view = field_of_view self.orientation = orientation @register_class('GrayscaleImage', CORE_NAMESPACE) class GrayscaleImage(Image): @docval(*get_docval(Image.__init__, 'name'), {'name': 'data', 'type': ('array_data', 'data'), 'doc': 'Data of grayscale image. Must be 2D where the dimensions represent x and y.', 'shape': (None, None)}, *get_docval(Image.__init__, 'resolution', 'description')) def __init__(self, **kwargs): super().__init__(**kwargs) @register_class('RGBImage', CORE_NAMESPACE) class RGBImage(Image): @docval(*get_docval(Image.__init__, 'name'), {'name': 'data', 'type': ('array_data', 'data'), 'doc': 'Data of color image. Must be 3D where the first and second dimensions represent x and y. ' 'The third dimension has length 3 and represents the RGB value.', 'shape': (None, None, 3)}, *get_docval(Image.__init__, 'resolution', 'description')) def __init__(self, **kwargs): super().__init__(**kwargs) @register_class('RGBAImage', CORE_NAMESPACE) class RGBAImage(Image): @docval(*get_docval(Image.__init__, 'name'), {'name': 'data', 'type': ('array_data', 'data'), 'doc': 'Data of color image with transparency. Must be 3D where the first and second dimensions ' 'represent x and y. The third dimension has length 4 and represents the RGBA value.', 'shape': (None, None, 4)}, *get_docval(Image.__init__, 'resolution', 'description')) def __init__(self, **kwargs): super().__init__(**kwargs) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5420275 pynwb-2.5.0/src/pynwb/io/0000755000175100001730000000000014467767767014652 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/__init__.py0000644000175100001730000000060214467767506016750 0ustar00runnerdockerfrom . import base as __base from . import core as __core from . import file as __file from . import behavior as __behavior from . import ecephys as __ecephys from . import epoch as __epoch from . import icephys as __icephys from . import image as __image from . import misc as __misc from . import ogen as __ogen from . import ophys as __ophys from . import retinotopy as __retinotopy ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/base.py0000644000175100001730000001103414467767506016124 0ustar00runnerdockerfrom hdmf.build import LinkBuilder from .core import NWBContainerMapper from .. import register_map from ..base import TimeSeries, ProcessingModule @register_map(ProcessingModule) class ModuleMap(NWBContainerMapper): def __init__(self, spec): super().__init__(spec) containers_spec = self.spec.get_neurodata_type('NWBDataInterface') table_spec = self.spec.get_neurodata_type('DynamicTable') self.map_spec('data_interfaces', containers_spec) self.map_spec('data_interfaces', table_spec) @register_map(TimeSeries) class TimeSeriesMap(NWBContainerMapper): def __init__(self, spec): super().__init__(spec) data_spec = self.spec.get_dataset('data') self.map_spec('unit', data_spec.get_attribute('unit')) self.map_spec('resolution', data_spec.get_attribute('resolution')) self.map_spec('conversion', data_spec.get_attribute('conversion')) self.map_spec('offset', data_spec.get_attribute('offset')) self.map_spec('continuity', data_spec.get_attribute('continuity')) timestamps_spec = self.spec.get_dataset('timestamps') self.map_spec('timestamps_unit', timestamps_spec.get_attribute('unit')) self.map_spec('interval', timestamps_spec.get_attribute('interval')) startingtime_spec = self.spec.get_dataset('starting_time') self.map_spec('starting_time_unit', startingtime_spec.get_attribute('unit')) self.map_spec('rate', startingtime_spec.get_attribute('rate')) # TODO map the sync group to something sync_spec = self.spec.get_group('sync') self.unmap(sync_spec) @NWBContainerMapper.object_attr("timestamps") def timestamps_attr(self, container, manager): ret = container.fields.get('timestamps') if isinstance(ret, TimeSeries): owner = ret curr = owner.fields.get('timestamps') while isinstance(curr, TimeSeries): owner = curr curr = owner.fields.get('timestamps') ts_builder = manager.build(owner) tstamps_builder = ts_builder['timestamps'] ret = LinkBuilder(tstamps_builder, 'timestamps') return ret @NWBContainerMapper.constructor_arg("timestamps") def timestamps_carg(self, builder, manager): tstamps_builder = builder.get('timestamps') if tstamps_builder is None: return None if isinstance(tstamps_builder, LinkBuilder): # if the parent of our target is available, return the parent object # Otherwise, return the dataset in the target builder # # NOTE: it is not available when data is externally linked # and we haven't explicitly read that file target = tstamps_builder.builder if target.parent is not None: return manager.construct(target.parent) else: return target.data else: return tstamps_builder.data @NWBContainerMapper.constructor_arg("data") def data_carg(self, builder, manager): # handle case where a TimeSeries is read and missing data timeseries_cls = manager.get_cls(builder) data_builder = builder.get('data') if data_builder is None: return timeseries_cls.DEFAULT_DATA if isinstance(data_builder, LinkBuilder): # NOTE: parent is not available when data is externally linked # and we haven't explicitly read that file target = data_builder.builder if target.parent is not None: return manager.construct(target.parent) else: return target.data return data_builder.data @NWBContainerMapper.constructor_arg("unit") def unit_carg(self, builder, manager): # handle case where a TimeSeries is read and missing unit timeseries_cls = manager.get_cls(builder) data_builder = builder.get('data') if data_builder is None: return timeseries_cls.DEFAULT_UNIT if isinstance(data_builder, LinkBuilder): # NOTE: parent is not available when data is externally linked # and we haven't explicitly read that file target = data_builder.builder if target.parent is not None: data_builder = manager.construct(target.parent) else: data_builder = target unit_value = data_builder.attributes.get('unit') if unit_value is None: return timeseries_cls.DEFAULT_UNIT return unit_value ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/behavior.py0000644000175100001730000000000014467767506017000 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/core.py0000644000175100001730000000520014467767506016140 0ustar00runnerdockerfrom hdmf.build import ObjectMapper, RegionBuilder from hdmf.common import VectorData from hdmf.utils import getargs, docval from hdmf.spec import AttributeSpec from hdmf.build import BuildManager from .. import register_map from pynwb.file import NWBFile from pynwb.core import NWBData, NWBContainer, ScratchData from pynwb.misc import Units class NWBBaseTypeMapper(ObjectMapper): @staticmethod def get_nwb_file(container): curr = container while curr is not None: if isinstance(curr, NWBFile): return curr curr = container.parent @register_map(NWBContainer) class NWBContainerMapper(NWBBaseTypeMapper): pass @register_map(NWBData) class NWBDataMap(NWBBaseTypeMapper): pass @register_map(ScratchData) class ScratchDataMap(NWBContainerMapper): def __init__(self, spec): super().__init__(spec) self.map_spec('description', spec.get_attribute('notes')) class NWBTableRegionMap(NWBDataMap): @ObjectMapper.constructor_arg('table') def carg_table(self, builder, manager): return manager.construct(builder.data.builder) @ObjectMapper.constructor_arg('region') def carg_region(self, builder, manager): if not isinstance(builder.data, RegionBuilder): raise ValueError("'builder' must be a RegionBuilder") return builder.data.region @register_map(VectorData) class VectorDataMap(ObjectMapper): @docval({"name": "spec", "type": AttributeSpec, "doc": "the spec to get the attribute value for"}, {"name": "container", "type": VectorData, "doc": "the container to get the attribute value from"}, {"name": "manager", "type": BuildManager, "doc": "the BuildManager used for managing this build"}, returns='the value of the attribute') def get_attr_value(self, **kwargs): ''' Get the value of the attribute corresponding to this spec from the given container ''' spec, container, manager = getargs('spec', 'container', 'manager', kwargs) # handle custom mapping of container Units.waveform_rate -> spec Units.waveform_mean.sampling_rate if isinstance(container.parent, Units): if container.name == 'waveform_mean' or container.name == 'waveform_sd': if spec.name == 'sampling_rate': return container.parent.waveform_rate if spec.name == 'unit': return container.parent.waveform_unit if container.name == 'spike_times': if spec.name == 'resolution': return container.parent.resolution return super().get_attr_value(**kwargs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/ecephys.py0000644000175100001730000000000014467767506016641 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/epoch.py0000644000175100001730000000431514467767506016314 0ustar00runnerdockerfrom hdmf.common.table import VectorData from hdmf.common.io.table import DynamicTableMap from .. import register_map from pynwb.epoch import TimeIntervals from pynwb.base import TimeSeriesReferenceVectorData @register_map(TimeIntervals) class TimeIntervalsMap(DynamicTableMap): pass @DynamicTableMap.constructor_arg('columns') def columns_carg(self, builder, manager): # handle the case when a TimeIntervals is read with a non-TimeSeriesReferenceVectorData "timeseries" column # this is the case for NWB schema v2.4 and earlier, where the timeseries column was a regular VectorData. timeseries_builder = builder.get('timeseries') # if we have a timeseries column and the type is VectorData instead of TimeSeriesReferenceVectorData if (timeseries_builder is not None and timeseries_builder.attributes['neurodata_type'] != 'TimeSeriesReferenceVectorData'): # override builder attributes timeseries_builder.attributes['neurodata_type'] = 'TimeSeriesReferenceVectorData' timeseries_builder.attributes['namespace'] = 'core' # construct new columns list columns = list() for dset_builder in builder.datasets.values(): dset_obj = manager.construct(dset_builder) # these have already been constructed # go through only the column datasets and replace the 'timeseries' column class in-place. if isinstance(dset_obj, VectorData): if dset_obj.name == 'timeseries': # replacing the class in-place is possible because the VectorData and # TimeSeriesReferenceVectorData have the same memory layout and the old and new # schema are compatible (i.e., only the neurodata_type was changed in 2.5) dset_obj.__class__ = TimeSeriesReferenceVectorData # Execute init logic specific for TimeSeriesReferenceVectorData dset_obj._init_internal() columns.append(dset_obj) # overwrite the columns constructor argument return columns # do not override return None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/file.py0000644000175100001730000002342214467767506016135 0ustar00runnerdockerfrom dateutil.parser import parse as dateutil_parse from hdmf.build import ObjectMapper from .. import register_map from ..file import NWBFile, Subject from ..core import ScratchData from .utils import get_nwb_version @register_map(NWBFile) class NWBFileMap(ObjectMapper): def __init__(self, spec): super().__init__(spec) acq_spec = self.spec.get_group('acquisition') self.unmap(acq_spec) self.map_spec('acquisition', acq_spec.get_neurodata_type('NWBDataInterface')) self.map_spec('acquisition', acq_spec.get_neurodata_type('DynamicTable')) # TODO: note that double mapping "acquisition" means __carg2spec and __attr2spec (both unused) # map "acquisition" to the last spec, in this case, DynamicTable ana_spec = self.spec.get_group('analysis') self.unmap(ana_spec) self.map_spec('analysis', ana_spec.get_neurodata_type('NWBContainer')) self.map_spec('analysis', ana_spec.get_neurodata_type('DynamicTable')) # map constructor arg and property 'stimulus' -> stimulus__presentation stimulus_spec = self.spec.get_group('stimulus') self.unmap(stimulus_spec) self.unmap(stimulus_spec.get_group('presentation')) self.unmap(stimulus_spec.get_group('templates')) self.map_spec('stimulus', stimulus_spec.get_group('presentation').get_neurodata_type('TimeSeries')) self.map_spec('stimulus_template', stimulus_spec.get_group('templates').get_neurodata_type('TimeSeries')) self.map_spec('stimulus_template', stimulus_spec.get_group('templates').get_neurodata_type('Images')) intervals_spec = self.spec.get_group('intervals') self.unmap(intervals_spec) self.map_spec('intervals', intervals_spec.get_neurodata_type('TimeIntervals')) epochs_spec = intervals_spec.get_group('epochs') self.map_spec('epochs', epochs_spec) trials_spec = intervals_spec.get_group('trials') self.map_spec('trials', trials_spec) invalid_times_spec = intervals_spec.get_group('invalid_times') self.map_spec('invalid_times', invalid_times_spec) general_spec = self.spec.get_group('general') self.unmap(general_spec) # map icephys metadata structures and tables icephys_spec = general_spec.get_group('intracellular_ephys') self.unmap(icephys_spec) self.map_spec('icephys_electrodes', icephys_spec.get_neurodata_type('IntracellularElectrode')) self.map_spec('sweep_table', icephys_spec.get_neurodata_type('SweepTable')) self.map_spec('intracellular_recordings', icephys_spec.get_neurodata_type('IntracellularRecordingsTable')) self.map_spec('icephys_simultaneous_recordings', icephys_spec.get_neurodata_type('SimultaneousRecordingsTable')) self.map_spec('icephys_sequential_recordings', icephys_spec.get_neurodata_type('SequentialRecordingsTable')) self.map_spec('icephys_repetitions', icephys_spec.get_neurodata_type('RepetitionsTable')) self.map_spec('icephys_experimental_conditions', icephys_spec.get_neurodata_type('ExperimentalConditionsTable')) # 'filtering' has been deprecated. add this mapping in the meantime icephys_filtering_spec = icephys_spec.get_dataset('filtering') self.unmap(icephys_filtering_spec) self.map_spec('icephys_filtering', icephys_filtering_spec) ecephys_spec = general_spec.get_group('extracellular_ephys') self.unmap(ecephys_spec) self.map_spec('electrodes', ecephys_spec.get_group('electrodes')) self.map_spec('electrode_groups', ecephys_spec.get_neurodata_type('ElectrodeGroup')) ogen_spec = general_spec.get_group('optogenetics') self.unmap(ogen_spec) self.map_spec('ogen_sites', ogen_spec.get_neurodata_type('OptogeneticStimulusSite')) ophys_spec = general_spec.get_group('optophysiology') self.unmap(ophys_spec) self.map_spec('imaging_planes', ophys_spec.get_neurodata_type('ImagingPlane')) general_datasets = ['data_collection', 'experiment_description', 'experimenter', 'institution', 'keywords', 'lab', 'notes', 'pharmacology', 'protocol', 'related_publications', 'session_id', 'slices', 'source_script', 'stimulus', 'surgery', 'virus'] for dataset_name in general_datasets: self.map_spec(dataset_name, general_spec.get_dataset(dataset_name)) # note: constructor arg and property 'stimulus' is already mapped above, so use a different name here self.map_spec('stimulus_notes', general_spec.get_dataset('stimulus')) self.map_spec('source_script_file_name', general_spec.get_dataset('source_script').get_attribute('file_name')) self.map_spec('subject', general_spec.get_group('subject')) device_spec = general_spec.get_group('devices') self.unmap(device_spec) self.map_spec('devices', device_spec.get_neurodata_type('Device')) self.map_spec('lab_meta_data', general_spec.get_neurodata_type('LabMetaData')) proc_spec = self.spec.get_group('processing') self.unmap(proc_spec) self.map_spec('processing', proc_spec.get_neurodata_type('ProcessingModule')) scratch_spec = self.spec.get_group('scratch') self.unmap(scratch_spec) self.map_spec('scratch_datas', scratch_spec.get_neurodata_type('ScratchData')) self.map_spec('scratch_containers', scratch_spec.get_neurodata_type('NWBContainer')) self.map_spec('scratch_containers', scratch_spec.get_neurodata_type('DynamicTable')) @ObjectMapper.object_attr('scratch_datas') def scratch_datas(self, container, manager): scratch = container.scratch ret = list() for s in scratch.values(): if isinstance(s, ScratchData): ret.append(s) return ret @ObjectMapper.object_attr('scratch_containers') def scratch_containers(self, container, manager): scratch = container.scratch ret = list() for s in scratch.values(): if not isinstance(s, ScratchData): ret.append(s) return ret @ObjectMapper.constructor_arg('scratch') def scratch(self, builder, manager): scratch = builder.get('scratch') ret = list() if scratch is not None: for g in scratch.groups.values(): ret.append(manager.construct(g)) for d in scratch.datasets.values(): ret.append(manager.construct(d)) return tuple(ret) if len(ret) > 0 else None @ObjectMapper.constructor_arg('session_start_time') def dateconversion(self, builder, manager): datestr = builder.get('session_start_time').data date = dateutil_parse(datestr) return date @ObjectMapper.constructor_arg('timestamps_reference_time') def dateconversion_trt(self, builder, manager): datestr = builder.get('timestamps_reference_time').data date = dateutil_parse(datestr) return date @ObjectMapper.constructor_arg('file_create_date') def dateconversion_list(self, builder, manager): datestr = builder.get('file_create_date').data dates = list(map(dateutil_parse, datestr)) return dates @ObjectMapper.constructor_arg('file_name') def name(self, builder, manager): return builder.name @ObjectMapper.constructor_arg('experimenter') def experimenter_carg(self, builder, manager): ret = None exp_bldr = builder['general'].get('experimenter') if exp_bldr is not None: if isinstance(exp_bldr.data, str): ret = (exp_bldr.data,) else: ret = tuple(exp_bldr.data) return ret @ObjectMapper.object_attr('experimenter') def experimenter_obj_attr(self, container, manager): ret = None if isinstance(container.experimenter, str): ret = (container.experimenter,) return ret @ObjectMapper.constructor_arg('related_publications') def publications_carg(self, builder, manager): ret = None pubs_bldr = builder['general'].get('related_publications') if pubs_bldr is not None: if isinstance(pubs_bldr.data, str): ret = (pubs_bldr.data,) else: ret = tuple(pubs_bldr.data) return ret @ObjectMapper.object_attr('related_publications') def publication_obj_attr(self, container, manager): ret = None if isinstance(container.related_publications, str): ret = (container.related_publications,) return ret @register_map(Subject) class SubjectMap(ObjectMapper): @ObjectMapper.constructor_arg('date_of_birth') def dateconversion(self, builder, manager): dob_builder = builder.get('date_of_birth') if dob_builder is None: return else: datestr = dob_builder.data date = dateutil_parse(datestr) return date @ObjectMapper.constructor_arg("age__reference") def age_reference_none(self, builder, manager): age_builder = builder.get("age") age_reference = None if age_builder is not None: age_reference = age_builder["attributes"].get("reference") if age_reference is None: if get_nwb_version(builder) < (2, 6, 0): return "unspecified" # this is handled specially in Subject.__init__ else: return "birth" return age_reference ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/icephys.py0000644000175100001730000000317214467767506016662 0ustar00runnerdockerfrom hdmf.common.io.table import DynamicTableMap from hdmf.common.io.alignedtable import AlignedDynamicTableMap from .. import register_map from .base import TimeSeriesMap from pynwb.icephys import VoltageClampSeries, IntracellularRecordingsTable @register_map(VoltageClampSeries) class VoltageClampSeriesMap(TimeSeriesMap): def __init__(self, spec): super().__init__(spec) fields_with_unit = ('capacitance_fast', 'capacitance_slow', 'resistance_comp_bandwidth', 'resistance_comp_correction', 'resistance_comp_prediction', 'whole_cell_capacitance_comp', 'whole_cell_series_resistance_comp') for field in fields_with_unit: field_spec = self.spec.get_dataset(field) self.map_spec('%s__unit' % field, field_spec.get_attribute('unit')) @register_map(IntracellularRecordingsTable) class IntracellularRecordingsTableMap(AlignedDynamicTableMap): """ Customize the mapping for AlignedDynamicTable """ def __init__(self, spec): super().__init__(spec) @DynamicTableMap.object_attr('electrodes') def electrodes(self, container, manager): return container.category_tables.get('electrodes', None) @DynamicTableMap.object_attr('stimuli') def stimuli(self, container, manager): return container.category_tables.get('stimuli', None) @DynamicTableMap.object_attr('responses') def responses(self, container, manager): return container.category_tables.get('responses', None) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/image.py0000644000175100001730000000057414467767506016303 0ustar00runnerdockerfrom .. import register_map from ..image import ImageSeries from .base import TimeSeriesMap @register_map(ImageSeries) class ImageSeriesMap(TimeSeriesMap): def __init__(self, spec): super().__init__(spec) external_file_spec = self.spec.get_dataset('external_file') self.map_spec('starting_frame', external_file_spec.get_attribute('starting_frame')) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/misc.py0000644000175100001730000000335114467767506016150 0ustar00runnerdockerfrom hdmf.common.io.table import DynamicTableMap from .. import register_map from pynwb.misc import Units @register_map(Units) class UnitsMap(DynamicTableMap): def __init__(self, spec): super().__init__(spec) @DynamicTableMap.constructor_arg('resolution') def resolution_carg(self, builder, manager): if 'spike_times' in builder: return builder['spike_times'].attributes.get('resolution') return None @DynamicTableMap.constructor_arg('waveform_rate') def waveform_rate_carg(self, builder, manager): return self._get_waveform_stat(builder, 'sampling_rate') @DynamicTableMap.constructor_arg('waveform_unit') def waveform_unit_carg(self, builder, manager): return self._get_waveform_stat(builder, 'unit') def _get_waveform_stat(self, builder, attribute): if 'waveform_mean' not in builder and 'waveform_sd' not in builder: return None mean_stat = None sd_stat = None if 'waveform_mean' in builder: mean_stat = builder['waveform_mean'].attributes.get(attribute) if 'waveform_sd' in builder: sd_stat = builder['waveform_sd'].attributes.get(attribute) if mean_stat is not None and sd_stat is not None: if mean_stat != sd_stat: # throw warning pass return mean_stat @DynamicTableMap.object_attr("electrodes") def electrodes_column(self, container, manager): ret = container.get('electrodes') if ret is None: return ret # set the electrode table if it hasn't been set yet if ret.target.table is None: ret.target.table = container.get_ancestor('NWBFile').electrodes return ret ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/ogen.py0000644000175100001730000000000014467767506016131 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/ophys.py0000644000175100001730000000227514467767506016363 0ustar00runnerdockerfrom hdmf.common.io.table import DynamicTableMap from .. import register_map from ..ophys import PlaneSegmentation, ImagingPlane from .core import NWBContainerMapper @register_map(PlaneSegmentation) class PlaneSegmentationMap(DynamicTableMap): def __init__(self, spec): super().__init__(spec) reference_images_spec = self.spec.get_group('reference_images').get_neurodata_type('ImageSeries') self.map_spec('reference_images', reference_images_spec) @register_map(ImagingPlane) class ImagingPlaneMap(NWBContainerMapper): def __init__(self, spec): super().__init__(spec) manifold_spec = self.spec.get_dataset('manifold') origin_coords_spec = self.spec.get_dataset('origin_coords') grid_spacing_spec = self.spec.get_dataset('grid_spacing') self.map_spec('unit', manifold_spec.get_attribute('unit')) self.map_spec('conversion', manifold_spec.get_attribute('conversion')) self.map_spec('origin_coords_unit', origin_coords_spec.get_attribute('unit')) self.map_spec('grid_spacing_unit', grid_spacing_spec.get_attribute('unit')) self.map_spec('optical_channel', self.spec.get_neurodata_type('OpticalChannel')) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/retinotopy.py0000644000175100001730000000066514467767506017436 0ustar00runnerdocker# from hdmf.build import ObjectMapper # from .. import register_map # from pynwb.retinotopy import ImagingRetinotopy # # # @register_map(ImagingRetinotopy) # class ImagingRetinotopyMap(ObjectMapper): # # def __init__(self, spec): # super().__init__(spec) # # datasets = ['sign_map', 'axis_1_phase_map'] # for dataset_name in datasets: # self.map_spec(dataset_name, spec.get_dataset(dataset_name)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/io/utils.py0000644000175100001730000000402614467767506016355 0ustar00runnerdockerimport re from typing import Tuple from hdmf.build import Builder def get_nwb_version(builder: Builder, include_prerelease=False) -> Tuple[int, ...]: """Get the version of the NWB file from the root of the given builder, as a tuple. If the "nwb_version" attribute on the root builder equals "2.5.1", then (2, 5, 1) is returned. If the "nwb_version" attribute on the root builder equals "2.5.1-alpha" and include_prerelease=False, then (2, 5, 1) is returned. If the "nwb_version" attribute on the root builder equals "2.5.1-alpha" and include_prerelease=True, then (2, 5, 1, "alpha") is returned. If the "nwb_version" attribute == "2.0b" (the only deviation from semantic versioning in the 2.x series), then if include_prerelease=True, (2, 0, 0, "b") is returned; else, (2, 0, 0) is returned. :param builder: Any builder within an NWB file. :type builder: Builder :param include_prerelease: Whether to include prerelease information in the returned tuple. :type include_prerelease: bool :return: The version of the NWB file, as a tuple. :rtype: tuple :raises ValueError: if the 'nwb_version' attribute is missing from the root of the NWB file. """ temp_builder = builder while temp_builder.parent is not None: temp_builder = temp_builder.parent root_builder = temp_builder nwb_version = root_builder.attributes.get("nwb_version") if nwb_version is None: raise ValueError("'nwb_version' attribute is missing from the root of the NWB file.") # handle special non-semver case if nwb_version == "2.0b": if not include_prerelease: return (2, 0, 0) else: return (2, 0, 0, "b") nwb_version_match = re.match(r"(\d+\.\d+\.\d+)", nwb_version)[0] # trim off any non-numeric symbols at end version_list = [int(i) for i in nwb_version_match.split(".")] if include_prerelease: prerelease_info = nwb_version[nwb_version.index("-")+1:] version_list.append(prerelease_info) return tuple(version_list) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5420275 pynwb-2.5.0/src/pynwb/legacy/0000755000175100001730000000000014467767767015507 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/__init__.py0000644000175100001730000000252614467767506017614 0ustar00runnerdockerfrom hdmf.utils import docval, getargs from .. import get_type_map, NWBContainer from .map import ObjectMapperLegacy as ObjectMapper __TYPE_MAP = get_type_map() # Register new ObjectMapper with the new TypeMap: __TYPE_MAP.register_map(NWBContainer, ObjectMapper) def get_type_map(**kwargs): """ Get a TypeMap to use for I/O for Allen Institute Brain Observatory files (NWB v1.0.6) """ return __TYPE_MAP # a function to register an object mapper for a container class @docval({"name": "container_cls", "type": type, "doc": "the Container class for which the given ObjectMapper class gets used for"}, {"name": "mapper_cls", "type": type, "doc": "the ObjectMapper class to use to map", 'default': None}, is_method=False) def register_map(**kwargs): """Register an ObjectMapper to use for a Container class type If mapper_cls is not specified, returns a decorator for registering an ObjectMapper class as the mapper for container_cls. If mapper_cls specified, register the class as the mapper for container_cls """ container_cls, mapper_cls = getargs('container_cls', 'mapper_cls', kwargs) def _dec(cls): __TYPE_MAP.register_map(container_cls, cls) return cls if mapper_cls is None: return _dec else: _dec(mapper_cls) from . import io # noqa: F401,E402 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5460274 pynwb-2.5.0/src/pynwb/legacy/io/0000755000175100001730000000000014467767767016116 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/__init__.py0000644000175100001730000000054514467767506020222 0ustar00runnerdockerfrom . import base as __base from . import behavior as __behavior from . import ecephys as __ecephys from . import epoch as __epoch from . import file as __file from . import icephys as __icephys from . import image as __image from . import misc as __misc from . import ogen as __ogen from . import ophys as __ophys from . import retinotopy as __retinotopy ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/base.py0000644000175100001730000000520314467767506017371 0ustar00runnerdockerfrom pynwb.base import TimeSeries, ProcessingModule from .. import ObjectMapper, register_map legacy_TimeSeries_missing_time_info_name_list = ('natural_movie_one_image_stack', 'natural_movie_two_image_stack', 'natural_movie_three_image_stack', 'natural_scenes_image_stack', 'locally_sparse_noise_image_stack', 'locally_sparse_noise_8deg_image_stack', 'locally_sparse_noise_4deg_image_stack') @register_map(ProcessingModule) class ModuleMap(ObjectMapper): def __init__(self, spec): super(ModuleMap, self).__init__(spec) containers_spec = self.spec.get_neurodata_type('NWBDataInterface') self.map_spec('containers', containers_spec) @ObjectMapper.constructor_arg('name') def name(self, *args): builder = args[0] return builder.name @ObjectMapper.constructor_arg('description') def carg_description(self, *args): return 'Brain Observatory Processing Module' @register_map(TimeSeries) class TimeSeriesMap(ObjectMapper): def __init__(self, spec): super(TimeSeriesMap, self).__init__(spec) data_spec = self.spec.get_dataset('data') self.map_attr('unit', data_spec.get_attribute('unit')) self.map_const_arg('unit', data_spec.get_attribute('unit')) self.map_attr('resolution', data_spec.get_attribute('resolution')) self.map_attr('conversion', data_spec.get_attribute('conversion')) timestamps_spec = self.spec.get_dataset('timestamps') self.map_attr('timestamps_unit', timestamps_spec.get_attribute('unit')) # self.map_attr('interval', timestamps_spec.get_attribute('interval')) starting_time_spec = self.spec.get_dataset('starting_time') self.map_attr('starting_time_unit', starting_time_spec.get_attribute('unit')) self.map_attr('rate', starting_time_spec.get_attribute('rate')) @ObjectMapper.constructor_arg('name') def carg_name(self, *args): builder = args[0] return builder.name @ObjectMapper.constructor_arg('starting_time') def carg_starting_time(self, *args): builder = args[0] if builder.name in legacy_TimeSeries_missing_time_info_name_list: return -1.0 @ObjectMapper.constructor_arg('rate') def carg_rate(self, *args): builder = args[0] if builder.name in legacy_TimeSeries_missing_time_info_name_list: return -1.0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/behavior.py0000644000175100001730000000235414467767506020262 0ustar00runnerdockerfrom pynwb.behavior import BehavioralTimeSeries, PupilTracking from pynwb.image import IndexSeries from .. import ObjectMapper, register_map @register_map(BehavioralTimeSeries) class BehavioralTimeSeriesMap(ObjectMapper): @ObjectMapper.constructor_arg('time_series') def carg_time_series(self, *args): builder = args[0] manager = args[1] subspecs = self.hack_get_subspec_values(builder, self.spec, manager) for subspec, value in subspecs.items(): const_arg = self.get_const_arg(subspec) if const_arg == 'time_series': for x in value: if not isinstance(x, IndexSeries): return x @register_map(PupilTracking) class PupilTrackingMap(ObjectMapper): @ObjectMapper.constructor_arg('time_series') def carg_time_series(self, *args): builder = args[0] manager = args[1] subspecs = self.hack_get_subspec_values(builder, self.spec, manager) for subspec, value in subspecs.items(): const_arg = self.get_const_arg(subspec) if const_arg == 'time_series': for x in value: if not isinstance(x, IndexSeries): return x ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/ecephys.py0000644000175100001730000000000014467767506020105 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/epoch.py0000644000175100001730000000162314467767506017557 0ustar00runnerdocker# from pynwb.epoch import Epochs, EpochTimeSeries from .. import ObjectMapper # from .. import register_map # @register_map(Epoch) class EpochMap(ObjectMapper): def __init__(self, spec): super(EpochMap, self).__init__(spec) start_spec = self.spec.get_dataset('start_time') stop_spec = self.spec.get_dataset('stop_time') self.map_const_arg('start', start_spec) self.map_const_arg('stop', stop_spec) epts_spec = self.spec.get_neurodata_type('EpochTimeSeries') self.map_spec('timeseries', epts_spec) @ObjectMapper.constructor_arg('name') def name(self, builder): return builder.name # @register_map(EpochTimeSeries) class EpochTimeSeriesMap(ObjectMapper): def __init__(self, spec): super(EpochTimeSeriesMap, self).__init__(spec) ts_spec = self.spec.get_link('timeseries') self.map_const_arg('ts', ts_spec) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/file.py0000644000175100001730000000330614467767506017400 0ustar00runnerdocker from pynwb.file import NWBFile from .. import ObjectMapper, register_map @register_map(NWBFile) class NWBFileMap(ObjectMapper): def __init__(self, spec): super(NWBFileMap, self).__init__(spec) raw_ts_spec = self.spec.get_group('acquisition').get_neurodata_type('NWBDataInterface') self.map_spec('acquisition', raw_ts_spec) stimulus_spec = self.spec.get_group('stimulus') presentation_ts_spec = stimulus_spec.get_group('presentation').get_neurodata_type('TimeSeries') self.map_spec('stimulus', presentation_ts_spec) stimulus_ts_spec = stimulus_spec.get_group('templates').get_neurodata_type('TimeSeries') self.map_spec('stimulus_template', stimulus_ts_spec) epochs_spec = self.spec.get_group('epochs') self.map_spec('epochs', epochs_spec.get_neurodata_type('Epoch')) general_spec = self.spec.get_group('general') self.map_spec( 'ic_electrodes', general_spec.get_group('intracellular_ephys').get_neurodata_type('IntracellularElectrode')) self.map_spec( 'ec_electrodes', general_spec.get_group('extracellular_ephys').get_neurodata_type('ElectrodeGroup')) self.map_spec( 'optogenetic_sites', general_spec.get_group('optogenetics').get_neurodata_type('OptogeneticStimulusSite')) self.map_spec( 'imaging_planes', general_spec.get_group('optophysiology').get_neurodata_type('ImagingPlane')) self.map_spec('modules', self.spec.get_group('processing').get_neurodata_type('ProcessingModule')) self.unmap(general_spec.get_dataset('stimulus')) @ObjectMapper.constructor_arg('file_name') def name(self, builder): return builder.name ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/icephys.py0000644000175100001730000000121014467767506020115 0ustar00runnerdockerfrom pynwb.icephys import PatchClampSeries from .. import ObjectMapper, register_map @register_map(PatchClampSeries) class PatchClampSeriesMap(ObjectMapper): @ObjectMapper.constructor_arg('electrode') def carg_electrode(self, *args): builder = args[0] manager = args[1] root = builder parent = root.parent while parent is not None: root = parent parent = root.parent elec_name = builder['electrode_name']['data'] elec_builder = root['general/intracellular_ephys/%s' % elec_name] electrode = manager.construct(elec_builder) return electrode ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/image.py0000644000175100001730000000052714467767506017545 0ustar00runnerdockerimport numpy as np from pynwb.image import ImageSeries from .. import ObjectMapper, register_map @register_map(ImageSeries) class ImageSeriesMap(ObjectMapper): @ObjectMapper.constructor_arg('data') def carg_data(self, *args): builder = args[0] if builder.name in ('corrected',): return np.array([-1.]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/misc.py0000644000175100001730000000046214467767506017414 0ustar00runnerdockerfrom pynwb.misc import AbstractFeatureSeries from .. import ObjectMapper, register_map @register_map(AbstractFeatureSeries) class AbstractFeatureSeriesMap(ObjectMapper): @ObjectMapper.constructor_arg('feature_units') def carg_feature_units(self, *args): return ['None', 'None', 'None'] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/ogen.py0000644000175100001730000000114314467767506017406 0ustar00runnerdockerfrom pynwb.ogen import OptogeneticSeries from .. import ObjectMapper, register_map @register_map(OptogeneticSeries) class OptogeneticSeriesMap(ObjectMapper): @ObjectMapper.constructor_arg('site') def carg_site(self, *args): builder = args[0] manager = args[1] root = builder parent = root.parent while parent is not None: root = parent parent = root.parent site_name = builder['site']['data'] site_builder = root['general/optogenetics/%s' % site_name] site = manager.construct(site_builder) return site ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/ophys.py0000644000175100001730000000413314467767506017622 0ustar00runnerdockerimport numpy as np from pynwb.ophys import PlaneSegmentation, TwoPhotonSeries from .. import ObjectMapper, register_map @register_map(PlaneSegmentation) class PlaneSegmentationMap(ObjectMapper): # This might be needed for 2.0 as well def __init__(self, spec): super(PlaneSegmentationMap, self).__init__(spec) reference_images_spec = self.spec.get_group('reference_images').get_neurodata_type('ImageSeries') self.map_spec('reference_images', reference_images_spec) @ObjectMapper.constructor_arg('imaging_plane') def carg_imaging_plane(self, *args): builder = args[0] if len(args) < 2: return builder.name # I think this is the hack you had in there before manager = args[1] root = builder parent = root.parent while parent is not None: root = parent parent = root.parent ip_name = builder['imaging_plane_name']['data'] ip_builder = root['general/optophysiology/%s' % ip_name] imaging_plane = manager.construct(ip_builder) return imaging_plane @register_map(TwoPhotonSeries) class TwoPhotonSeriesMap(ObjectMapper): @ObjectMapper.constructor_arg('data') def carg_data(self, *args): builder = args[0] if builder.name in ('2p_image_series',): return np.array([-1.]) @ObjectMapper.constructor_arg('unit') def carg_unit(self, *args): builder = args[0] if builder.name in ('2p_image_series',): return 'None' @ObjectMapper.constructor_arg('imaging_plane') def carg_imaging_plane(self, *args): builder = args[0] if len(args) < 2: return builder.name # I think this is the hack you had in there before manager = args[1] root = builder parent = root.parent while parent is not None: root = parent parent = root.parent ip_name = builder['imaging_plane']['data'] ip_builder = root['general/optophysiology/%s' % ip_name] imaging_plane = manager.construct(ip_builder) return imaging_plane ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/io/retinotopy.py0000644000175100001730000000000014467767506020661 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/legacy/map.py0000644000175100001730000001353214467767506016631 0ustar00runnerdocker from hdmf.build import ObjectMapper, TypeMap from hdmf.build.builders import GroupBuilder def decode(val): if isinstance(val, bytes): return val.decode('UTF-8') else: return val class ObjectMapperLegacy(ObjectMapper): @ObjectMapper.constructor_arg('source') def source_gettr(self, builder, manager): if 'source' in builder.attributes: return builder.attributes['source'] else: return 'No known source' class TypeMapLegacy(TypeMap): def get_builder_dt(self, builder): # noqa: C901 ''' For a given builder, return the neurodata_type. In this legacy TypeMap, the builder may have out-of-spec neurodata_type; this function coerces this to a 2.0 compatible version. ''' if builder.name == 'root': return 'NWBFile' elif builder.name == 'subject' and builder.parent.name == 'general': return 'Subject' else: attrs = builder.attributes ndt = attrs.get('neurodata_type') if ndt == 'Module': return 'ProcessingModule' elif ndt == 'Interface': return builder.name elif ndt == 'Epoch': return 'Epoch' elif ndt == 'TimeSeries': ancestry = decode(attrs['ancestry'][-1]) if ancestry == 'TwoPhotonSeries' and decode(builder.name) == 'corrected': return 'ImageSeries' else: return ancestry elif ndt == 'Custom': parent_ndt = self.get_builder_dt(builder.parent) if parent_ndt == 'ImageSegmentation' and builder.name in ('roi_ids', 'cell_specimen_ids'): return None elif parent_ndt == 'PlaneSegmentation' and builder.name in ('roi_list', 'imaging_plane_name'): return None elif parent_ndt == 'IntervalSeries' and builder.name in ('frame_duration',): return None elif parent_ndt == 'TimeSeries' and builder.name in ('feature_description', 'bits_per_pixel', 'dimension', 'field_of_view', 'format'): return None elif parent_ndt == 'ImagingPlane' and builder.parent.name in ('imaging_plane_1',): return None elif parent_ndt == 'AbstractFeatureSeries' and builder.name in ('frame_duration',): return None elif parent_ndt == 'IndexSeries' and builder.name in ('frame_duration',): return None elif builder.parent.name == 'general': return None elif parent_ndt == 'RoiResponseSeries' and builder.name in ('r', 'neuropil_traces_path', 'rmse', 'comments'): return None elif parent_ndt == 'SpatialSeries' and builder.name in ('features'): return None else: raise RuntimeError(('Unable to determine neurodata_type: attrs["neurodata_type"]: "Custom",' 'parent.neurodata_type: %s' % parent_ndt)) else: parent_ndt = self.get_builder_dt(builder.parent) if parent_ndt == 'Epoch': return 'EpochTimeSeries' elif parent_ndt == 'MotionCorrection': return 'CorrectedImageStack' elif parent_ndt == 'ImagingPlane' and isinstance(builder, GroupBuilder): return 'OpticalChannel' elif parent_ndt == 'ImageSegmentation': return 'PlaneSegmentation' elif parent_ndt == 'PlaneSegmentation': if builder.name in ('roi_list', 'imaging_plane_name'): return None else: return 'ROI' else: parent_names = { 'extracellular_ephys': 'ElectrodeGroup', 'intracellular_ephys': 'IntracellularElectrodeGroup', 'optophysiology': 'ImagingPlane', 'optogenetics': 'OptogeneticStimulusSite', 'root': None, 'xy_translation': None, 'imaging_plane_1': None, 'running_speed': None, 'general': None, '2p_image_series': None, 'natural_movie_one_stimulus': None, 'natural_scenes_stimulus': None, 'devices': None, 'spontaneous_stimulus': None, 'static_gratings_stimulus': None, 'maximum_intensity_projection_image': None, 'imaging_plane_1_neuropil_response': None, 'imaging_plane_1_demixed_signal': None, 'corrected': None, 'running_speed_index': None, 'pupil_size_index': None, 'pupil_size': None, 'pupil_location': None, 'pupil_location_spherical': None } return decode(parent_names.get(builder.parent.name)) def get_builder_ns(self, builder): return 'core' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/misc.py0000644000175100001730000004206114467767506015542 0ustar00runnerdockerimport warnings from collections.abc import Iterable from bisect import bisect_left, bisect_right import numpy as np from hdmf.utils import docval, getargs, popargs, popargs_to_dict, get_docval from . import register_class, CORE_NAMESPACE from .base import TimeSeries from .ecephys import ElectrodeGroup from hdmf.common import DynamicTable, DynamicTableRegion @register_class('AnnotationSeries', CORE_NAMESPACE) class AnnotationSeries(TimeSeries): """Stores text-based records about the experiment. To use the AnnotationSeries, add records individually through add_annotation(). Alternatively, if all annotations are already stored in a list or numpy array, set the data and timestamps in the constructor. """ __nwbfields__ = () @docval(*get_docval(TimeSeries.__init__, 'name'), # required {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': (None,), 'doc': 'The annotations over time. Must be 1D.', 'default': list()}, *get_docval(TimeSeries.__init__, 'timestamps', 'comments', 'description')) def __init__(self, **kwargs): name, data, timestamps = popargs('name', 'data', 'timestamps', kwargs) super().__init__(name=name, data=data, unit='n/a', resolution=-1.0, timestamps=timestamps, **kwargs) @docval({'name': 'time', 'type': float, 'doc': 'The time for the annotation'}, {'name': 'annotation', 'type': str, 'doc': 'the annotation'}) def add_annotation(self, **kwargs): """Add an annotation.""" time, annotation = getargs('time', 'annotation', kwargs) self.fields['timestamps'].append(time) self.fields['data'].append(annotation) @register_class('AbstractFeatureSeries', CORE_NAMESPACE) class AbstractFeatureSeries(TimeSeries): """ Represents the salient features of a data stream. Typically this will be used for things like a visual grating stimulus, where the bulk of data (each frame sent to the graphics card) is bulky and not of high value, while the salient characteristics (eg, orientation, spatial frequency, contrast, etc) are what important and are what are used for analysis """ __nwbfields__ = ('feature_units', 'features') @docval(*get_docval(TimeSeries.__init__, 'name'), # required {'name': 'feature_units', 'type': Iterable, 'shape': (None, ), # required 'doc': 'The unit of each feature'}, {'name': 'features', 'type': Iterable, 'shape': (None, ), # required 'doc': 'Description of each feature'}, {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': ((None,), (None, None)), 'doc': ('The data values. May be 1D or 2D. The first dimension must be time. The optional second ' 'dimension represents features'), 'default': list()}, *get_docval(TimeSeries.__init__, 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'offset')) def __init__(self, **kwargs): name, data, features, feature_units = popargs('name', 'data', 'features', 'feature_units', kwargs) super().__init__(name=name, data=data, unit="see 'feature_units'", **kwargs) self.features = features self.feature_units = feature_units @docval({'name': 'time', 'type': float, 'doc': 'the time point of this feature'}, {'name': 'features', 'type': (list, np.ndarray), 'doc': 'the feature values for this time point'}) def add_features(self, **kwargs): time, features = getargs('time', 'features', kwargs) if isinstance(self.timestamps, list) and isinstance(self.data, list): self.timestamps.append(time) self.data.append(features) else: raise ValueError('Can only add feature if timestamps and data are lists') @register_class('IntervalSeries', CORE_NAMESPACE) class IntervalSeries(TimeSeries): """ Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way. """ __nwbfields__ = () @docval(*get_docval(TimeSeries.__init__, 'name'), # required {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': (None,), 'doc': ('The data values. Must be 1D, where the first dimension must be time. Values are >0 if ' 'interval started, <0 if interval ended.'), 'default': list()}, *get_docval(TimeSeries.__init__, 'timestamps', 'comments', 'description', 'control', 'control_description')) def __init__(self, **kwargs): name, data, timestamps = popargs('name', 'data', 'timestamps', kwargs) self.__interval_timestamps = timestamps self.__interval_data = data super().__init__(name=name, data=data, unit='n/a', resolution=-1.0, timestamps=timestamps, **kwargs) @docval({'name': 'start', 'type': float, 'doc': 'The start time of the interval'}, {'name': 'stop', 'type': float, 'doc': 'The stop time of the interval'}) def add_interval(self, **kwargs): start, stop = getargs('start', 'stop', kwargs) self.__interval_timestamps.append(start) self.__interval_timestamps.append(stop) self.__interval_data.append(1) self.__interval_data.append(-1) @property def data(self): return self.__interval_data @property def timestamps(self): return self.__interval_timestamps @register_class('Units', CORE_NAMESPACE) class Units(DynamicTable): """ Event times of observed units (e.g. cell, synapse, etc.). """ __fields__ = ( 'waveform_rate', 'waveform_unit', 'resolution' ) waveforms_desc = ('Individual waveforms for each spike. If the dataset is three-dimensional, the third dimension ' 'shows the response from different electrodes that all observe this unit simultaneously. In this' ' case, the `electrodes` column of this Units table should be used to indicate which electrodes ' 'are associated with this unit, and the electrodes dimension here should be in the same order as' ' the electrodes referenced in the `electrodes` column of this table.') __columns__ = ( {'name': 'spike_times', 'description': 'the spike times for each unit', 'index': True}, {'name': 'obs_intervals', 'description': 'the observation intervals for each unit', 'index': True}, {'name': 'electrodes', 'description': 'the electrodes that each spike unit came from', 'index': True, 'table': True}, {'name': 'electrode_group', 'description': 'the electrode group that each spike unit came from'}, {'name': 'waveform_mean', 'description': 'the spike waveform mean for each spike unit'}, {'name': 'waveform_sd', 'description': 'the spike waveform standard deviation for each spike unit'}, {'name': 'waveforms', 'description': waveforms_desc, 'index': 2} ) @docval({'name': 'name', 'type': str, 'doc': 'Name of this Units interface', 'default': 'Units'}, *get_docval(DynamicTable.__init__, 'id', 'columns', 'colnames'), {'name': 'description', 'type': str, 'doc': 'a description of what is in this table', 'default': None}, {'name': 'electrode_table', 'type': DynamicTable, 'doc': 'the table that the *electrodes* column indexes', 'default': None}, {'name': 'waveform_rate', 'type': float, 'doc': 'Sampling rate of the waveform means', 'default': None}, {'name': 'waveform_unit', 'type': str, 'doc': 'Unit of measurement of the waveform means', 'default': 'volts'}, {'name': 'resolution', 'type': float, 'doc': 'The smallest possible difference between two spike times', 'default': None} ) def __init__(self, **kwargs): args_to_set = popargs_to_dict(("waveform_rate", "waveform_unit", "resolution"), kwargs) electrode_table = popargs("electrode_table", kwargs) if kwargs['description'] is None: kwargs['description'] = "data on spiking units" super().__init__(**kwargs) for key, val in args_to_set.items(): setattr(self, key, val) if 'spike_times' not in self.colnames: self.__has_spike_times = False self.__electrode_table = electrode_table @docval({'name': 'spike_times', 'type': 'array_data', 'doc': 'the spike times for each unit', 'default': None, 'shape': (None,)}, {'name': 'obs_intervals', 'type': 'array_data', 'doc': 'the observation intervals (valid times) for each unit. All spike_times for a given unit ' + 'should fall within these intervals. [[start1, end1], [start2, end2], ...]', 'default': None, 'shape': (None, 2)}, {'name': 'electrodes', 'type': 'array_data', 'doc': 'the electrodes that each unit came from', 'default': None}, {'name': 'electrode_group', 'type': ElectrodeGroup, 'default': None, 'doc': 'the electrode group that each unit came from'}, {'name': 'waveform_mean', 'type': 'array_data', 'doc': 'the spike waveform mean for each unit. Shape is (time,) or (time, electrodes)', 'default': None}, {'name': 'waveform_sd', 'type': 'array_data', 'default': None, 'doc': 'the spike waveform standard deviation for each unit. Shape is (time,) or (time, electrodes)'}, {'name': 'waveforms', 'type': 'array_data', 'default': None, 'doc': waveforms_desc, 'shape': ((None, None), (None, None, None))}, {'name': 'id', 'type': int, 'default': None, 'doc': 'the id for each unit'}, allow_extra=True) def add_unit(self, **kwargs): """ Add a unit to this table """ super().add_row(**kwargs) if 'electrodes' in self: elec_col = self['electrodes'].target if elec_col.table is None: if self.__electrode_table is None: nwbfile = self.get_ancestor(data_type='NWBFile') elec_col.table = nwbfile.electrodes if elec_col.table is None: warnings.warn('Reference to electrode table that does not yet exist') else: elec_col.table = self.__electrode_table @docval({'name': 'index', 'type': (int, list, tuple, np.ndarray), 'doc': 'the index of the unit in unit_ids to retrieve spike times for'}, {'name': 'in_interval', 'type': (tuple, list), 'doc': 'only return values within this interval', 'default': None, 'shape': (2,)}) def get_unit_spike_times(self, **kwargs): index, in_interval = getargs('index', 'in_interval', kwargs) if type(index) in (list, tuple): return [self.get_unit_spike_times(i, in_interval=in_interval) for i in index] if in_interval is None: return np.asarray(self['spike_times'][index]) else: st = self['spike_times'] unit_start = 0 if index == 0 else st.data[index - 1] unit_stop = st.data[index] start_time, stop_time = in_interval ind_start = bisect_left(st.target, start_time, unit_start, unit_stop) ind_stop = bisect_right(st.target, stop_time, ind_start, unit_stop) return np.asarray(st.target[ind_start:ind_stop]) @docval({'name': 'index', 'type': int, 'doc': 'the index of the unit in unit_ids to retrieve observation intervals for'}) def get_unit_obs_intervals(self, **kwargs): index = getargs('index', kwargs) return np.asarray(self['obs_intervals'][index]) @register_class('DecompositionSeries', CORE_NAMESPACE) class DecompositionSeries(TimeSeries): """ Stores product of spectral analysis """ __nwbfields__ = ('metric', {'name': 'source_timeseries', 'child': False, 'doc': 'the input TimeSeries from this analysis'}, {'name': 'source_channels', 'child': True, 'doc': 'the channels that provided the source data'}, {'name': 'bands', 'doc': 'the bands that the signal is decomposed into', 'child': True}) # value used when a DecompositionSeries is read and missing data DEFAULT_DATA = np.ndarray(shape=(0, 0, 0), dtype=np.uint8) @docval(*get_docval(TimeSeries.__init__, 'name'), # required {'name': 'data', 'type': ('array_data', 'data', TimeSeries), # required 'doc': ('The data values. Must be 3D, where the first dimension must be time, the second dimension must ' 'be channels, and the third dimension must be bands.'), 'shape': (None, None, None)}, *get_docval(TimeSeries.__init__, 'description'), {'name': 'metric', 'type': str, # required 'doc': "metric of analysis. recommended: 'phase', 'amplitude', 'power'"}, {'name': 'unit', 'type': str, 'doc': 'SI unit of measurement', 'default': 'no unit'}, {'name': 'bands', 'type': DynamicTable, 'doc': 'a table for describing the frequency bands that the signal was decomposed into', 'default': None}, {'name': 'source_timeseries', 'type': TimeSeries, 'doc': 'the input TimeSeries from this analysis', 'default': None}, {'name': 'source_channels', 'type': DynamicTableRegion, 'doc': ('The channels that provided the source data. In the case of electrical recordings this is ' 'typically a DynamicTableRegion pointing to the electrodes table at NWBFile.electrodes, ' 'similar to ElectricalSeries.electrodes.'), 'default': None}, *get_docval(TimeSeries.__init__, 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'control', 'control_description', 'offset')) def __init__(self, **kwargs): metric, source_timeseries, bands, source_channels = popargs('metric', 'source_timeseries', 'bands', 'source_channels', kwargs) super().__init__(**kwargs) self.source_timeseries = source_timeseries self.source_channels = source_channels if self.source_timeseries is None and self.source_channels is None: warnings.warn("Neither source_timeseries nor source_channels is present in DecompositionSeries. It is " "recommended to indicate the source timeseries if it is present, or else to link to the " "corresponding source_channels. (Optional)") self.metric = metric if bands is None: bands = DynamicTable( name="bands", description="data about the frequency bands that the signal was decomposed into" ) self.bands = bands def __check_column(self, name, desc): if name not in self.bands.colnames: self.bands.add_column(name, desc) @docval({'name': 'band_name', 'type': str, 'doc': 'the name of the frequency band', 'default': None}, {'name': 'band_limits', 'type': ('array_data', 'data'), 'default': None, 'doc': 'low and high frequencies of bandpass filter in Hz'}, {'name': 'band_mean', 'type': float, 'doc': 'the mean of Gaussian filters in Hz', 'default': None}, {'name': 'band_stdev', 'type': float, 'doc': 'the standard deviation of Gaussian filters in Hz', 'default': None}, allow_extra=True) def add_band(self, **kwargs): """ Add ROI data to this """ band_name, band_limits, band_mean, band_stdev = getargs('band_name', 'band_limits', 'band_mean', 'band_stdev', kwargs) if band_name is not None: self.__check_column('band_name', "the name of the frequency band (recommended: 'alpha', 'beta', 'gamma', " "'delta', 'high gamma'") if band_name is not None: self.__check_column('band_limits', 'low and high frequencies of bandpass filter in Hz') if band_mean is not None: self.__check_column('band_mean', 'the mean of Gaussian filters in Hz') if band_stdev is not None: self.__check_column('band_stdev', 'the standard deviation of Gaussian filters in Hz') self.bands.add_row({k: v for k, v in kwargs.items() if v is not None}) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5380273 pynwb-2.5.0/src/pynwb/nwb-schema/0000755000175100001730000000000014467767767016267 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5460274 pynwb-2.5.0/src/pynwb/nwb-schema/core/0000755000175100001730000000000014467767767017217 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.base.yaml0000644000175100001730000002233514467767510021571 0ustar00runnerdockerdatasets: - neurodata_type_def: NWBData neurodata_type_inc: Data doc: An abstract data type for a dataset. - neurodata_type_def: TimeSeriesReferenceVectorData neurodata_type_inc: VectorData default_name: timeseries dtype: - name: idx_start dtype: int32 doc: Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time. - name: count dtype: int32 doc: Number of data samples available in this time series, during this epoch - name: timeseries dtype: target_type: TimeSeries reftype: object doc: The TimeSeries that this index applies to doc: Column storing references to a TimeSeries (rows). For each TimeSeries this VectorData column stores the start_index and count to indicate the range in time to be selected as well as an object reference to the TimeSeries. - neurodata_type_def: Image neurodata_type_inc: NWBData dtype: numeric dims: - - x - y - - x - y - r, g, b - - x - y - r, g, b, a shape: - - null - null - - null - null - 3 - - null - null - 4 doc: An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)). attributes: - name: resolution dtype: float32 doc: Pixel resolution of the image, in pixels per centimeter. required: false - name: description dtype: text doc: Description of the image. required: false - neurodata_type_def: ImageReferences neurodata_type_inc: NWBData dtype: target_type: Image reftype: object dims: - num_images shape: - null doc: Ordered dataset of references to Image objects. groups: - neurodata_type_def: NWBContainer neurodata_type_inc: Container doc: An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers. - neurodata_type_def: NWBDataInterface neurodata_type_inc: NWBContainer doc: An abstract data type for a generic container storing collections of data, as opposed to metadata. - neurodata_type_def: TimeSeries neurodata_type_inc: NWBDataInterface doc: General purpose time series. attributes: - name: description dtype: text default_value: no description doc: Description of the time series. required: false - name: comments dtype: text default_value: no comments doc: Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string. required: false datasets: - name: data dims: - - num_times - - num_times - num_DIM2 - - num_times - num_DIM2 - num_DIM3 - - num_times - num_DIM2 - num_DIM3 - num_DIM4 shape: - - null - - null - null - - null - null - null - - null - null - null - null doc: Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file. attributes: - name: conversion dtype: float32 default_value: 1.0 doc: Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9. required: false - name: offset dtype: float32 default_value: 0.0 doc: Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units. required: false - name: resolution dtype: float32 default_value: -1.0 doc: Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0. required: false - name: unit dtype: text doc: Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'. - name: continuity dtype: text doc: Optionally describe the continuity of the data. Can be "continuous", "instantaneous", or "step". For example, a voltage trace would be "continuous", because samples are recorded from a continuous process. An array of lick times would be "instantaneous", because the data represents distinct moments in time. Times of image presentations would be "step" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable. required: false - name: starting_time dtype: float64 doc: Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute. quantity: '?' attributes: - name: rate dtype: float32 doc: Sampling rate, in Hz. - name: unit dtype: text value: seconds doc: Unit of measurement for time, which is fixed to 'seconds'. - name: timestamps dtype: float64 dims: - num_times shape: - null doc: Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. quantity: '?' attributes: - name: interval dtype: int32 value: 1 doc: Value is '1' - name: unit dtype: text value: seconds doc: Unit of measurement for timestamps, which is fixed to 'seconds'. - name: control dtype: uint8 dims: - num_times shape: - null doc: Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data. quantity: '?' - name: control_description dtype: text dims: - num_control_values shape: - null doc: Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0. quantity: '?' groups: - name: sync doc: Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes. quantity: '?' - neurodata_type_def: ProcessingModule neurodata_type_inc: NWBContainer doc: A collection of processed data. attributes: - name: description dtype: text doc: Description of this collection of processed data. groups: - neurodata_type_inc: NWBDataInterface doc: Data objects stored in this collection. quantity: '*' - neurodata_type_inc: DynamicTable doc: Tables stored in this collection. quantity: '*' - neurodata_type_def: Images neurodata_type_inc: NWBDataInterface default_name: Images doc: A collection of images with an optional way to specify the order of the images using the "order_of_images" dataset. An order must be specified if the images are referenced by index, e.g., from an IndexSeries. attributes: - name: description dtype: text doc: Description of this collection of images. datasets: - neurodata_type_inc: Image doc: Images stored in this collection. quantity: '+' - name: order_of_images neurodata_type_inc: ImageReferences doc: Ordered dataset of references to Image objects stored in the parent group. Each Image object in the Images group should be stored once and only once, so the dataset should have the same length as the number of images. quantity: '?' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.behavior.yaml0000644000175100001730000001175314467767510022460 0ustar00runnerdockergroups: - neurodata_type_def: SpatialSeries neurodata_type_inc: TimeSeries doc: "Direction, e.g., of gaze or travel, or position. The TimeSeries::data field\ \ is a 2D array storing position or direction relative to some reference frame.\ \ Array structure: [num measurements] [num dimensions]. Each SpatialSeries has\ \ a text dataset reference_frame that indicates the zero-position, or the zero-axes\ \ for direction. For example, if representing gaze direction, 'straight-ahead'\ \ might be a specific pixel on the monitor, or some other point in space. For\ \ position data, the 0,0 point might be the top-left corner of an enclosure, as\ \ viewed from the tracking camera. The unit of data will indicate how to interpret\ \ SpatialSeries values." datasets: - name: data dtype: numeric dims: - - num_times - - num_times - x - - num_times - x,y - - num_times - x,y,z shape: - - null - - null - 1 - - null - 2 - - null - 3 doc: 1-D or 2-D array storing position or direction relative to some reference frame. attributes: - name: unit dtype: text default_value: meters doc: Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'. required: false - name: reference_frame dtype: text doc: Description defining what exactly 'straight-ahead' means. quantity: '?' - neurodata_type_def: BehavioralEpochs neurodata_type_inc: NWBDataInterface default_name: BehavioralEpochs doc: TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data. groups: - neurodata_type_inc: IntervalSeries doc: IntervalSeries object containing start and stop times of epochs. quantity: '*' - neurodata_type_def: BehavioralEvents neurodata_type_inc: NWBDataInterface default_name: BehavioralEvents doc: TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details. groups: - neurodata_type_inc: TimeSeries doc: TimeSeries object containing behavioral events. quantity: '*' - neurodata_type_def: BehavioralTimeSeries neurodata_type_inc: NWBDataInterface default_name: BehavioralTimeSeries doc: TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details. groups: - neurodata_type_inc: TimeSeries doc: TimeSeries object containing continuous behavioral data. quantity: '*' - neurodata_type_def: PupilTracking neurodata_type_inc: NWBDataInterface default_name: PupilTracking doc: Eye-tracking data, representing pupil size. groups: - neurodata_type_inc: TimeSeries doc: TimeSeries object containing time series data on pupil size. quantity: '+' - neurodata_type_def: EyeTracking neurodata_type_inc: NWBDataInterface default_name: EyeTracking doc: Eye-tracking data, representing direction of gaze. groups: - neurodata_type_inc: SpatialSeries doc: SpatialSeries object containing data measuring direction of gaze. quantity: '*' - neurodata_type_def: CompassDirection neurodata_type_inc: NWBDataInterface default_name: CompassDirection doc: With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees. groups: - neurodata_type_inc: SpatialSeries doc: SpatialSeries object containing direction of gaze travel. quantity: '*' - neurodata_type_def: Position neurodata_type_inc: NWBDataInterface default_name: Position doc: Position data, whether along the x, x/y or x/y/z axis. groups: - neurodata_type_inc: SpatialSeries doc: SpatialSeries object containing position data. quantity: '+' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.device.yaml0000644000175100001730000000073714467767510022120 0ustar00runnerdockergroups: - neurodata_type_def: Device neurodata_type_inc: NWBContainer doc: Metadata about a data acquisition device, e.g., recording system, electrode, microscope. attributes: - name: description dtype: text doc: Description of the device (e.g., model, firmware version, processing software version, etc.) as free-form text. required: false - name: manufacturer dtype: text doc: The name of the manufacturer of the device. required: false ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.ecephys.yaml0000644000175100001730000002744014467767510022321 0ustar00runnerdockergroups: - neurodata_type_def: ElectricalSeries neurodata_type_inc: TimeSeries doc: A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels. attributes: - name: filtering dtype: text doc: Filtering applied to all channels of the data. For example, if this ElectricalSeries represents high-pass-filtered data (also known as AP Band), then this value could be "High-pass 4-pole Bessel filter at 500 Hz". If this ElectricalSeries represents low-pass-filtered LFP data and the type of filter is unknown, then this value could be "Low-pass filter at 300 Hz". If a non-standard filter type is used, provide as much detail about the filter properties as possible. required: false datasets: - name: data dtype: numeric dims: - - num_times - - num_times - num_channels - - num_times - num_channels - num_samples shape: - - null - - null - null - - null - null - null doc: Recorded voltage data. attributes: - name: unit dtype: text value: volts doc: Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion', followed by 'channel_conversion' (if present), and then add 'offset'. - name: electrodes neurodata_type_inc: DynamicTableRegion doc: DynamicTableRegion pointer to the electrodes that this time series was generated from. - name: channel_conversion dtype: float32 dims: - num_channels shape: - null doc: Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels. quantity: '?' attributes: - name: axis dtype: int32 value: 1 doc: The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1. - neurodata_type_def: SpikeEventSeries neurodata_type_inc: ElectricalSeries doc: "Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode)." datasets: - name: data dtype: numeric dims: - - num_events - num_samples - - num_events - num_channels - num_samples shape: - - null - null - - null - null - null doc: Spike waveforms. attributes: - name: unit dtype: text value: volts doc: Unit of measurement for waveforms, which is fixed to 'volts'. - name: timestamps dtype: float64 dims: - num_times shape: - null doc: Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here. attributes: - name: interval dtype: int32 value: 1 doc: Value is '1' - name: unit dtype: text value: seconds doc: Unit of measurement for timestamps, which is fixed to 'seconds'. - neurodata_type_def: FeatureExtraction neurodata_type_inc: NWBDataInterface default_name: FeatureExtraction doc: Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source. datasets: - name: description dtype: text dims: - num_features shape: - null doc: Description of features (eg, ''PC1'') for each of the extracted features. - name: features dtype: float32 dims: - num_events - num_channels - num_features shape: - null - null - null doc: Multi-dimensional array of features extracted from each event. - name: times dtype: float64 dims: - num_events shape: - null doc: Times of events that features correspond to (can be a link). - name: electrodes neurodata_type_inc: DynamicTableRegion doc: DynamicTableRegion pointer to the electrodes that this time series was generated from. - neurodata_type_def: EventDetection neurodata_type_inc: NWBDataInterface default_name: EventDetection doc: Detected spike events from voltage trace(s). datasets: - name: detection_method dtype: text doc: Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values. - name: source_idx dtype: int32 dims: - num_events shape: - null doc: Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data. - name: times dtype: float64 dims: - num_events shape: - null doc: Timestamps of events, in seconds. attributes: - name: unit dtype: text value: seconds doc: Unit of measurement for event times, which is fixed to 'seconds'. links: - name: source_electricalseries target_type: ElectricalSeries doc: Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here. - neurodata_type_def: EventWaveform neurodata_type_inc: NWBDataInterface default_name: EventWaveform doc: Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition. groups: - neurodata_type_inc: SpikeEventSeries doc: SpikeEventSeries object(s) containing detected spike event waveforms. quantity: '*' - neurodata_type_def: FilteredEphys neurodata_type_inc: NWBDataInterface default_name: FilteredEphys doc: Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries 'filtering' attribute. groups: - neurodata_type_inc: ElectricalSeries doc: ElectricalSeries object(s) containing filtered electrophysiology data. quantity: '+' - neurodata_type_def: LFP neurodata_type_inc: NWBDataInterface default_name: LFP doc: LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries 'filtering' attribute. groups: - neurodata_type_inc: ElectricalSeries doc: ElectricalSeries object(s) containing LFP data for one or more channels. quantity: '+' - neurodata_type_def: ElectrodeGroup neurodata_type_inc: NWBContainer doc: A physical grouping of electrodes, e.g. a shank of an array. attributes: - name: description dtype: text doc: Description of this electrode group. - name: location dtype: text doc: Location of electrode group. Specify the area, layer, comments on estimation of area/layer, etc. Use standard atlas names for anatomical regions when possible. datasets: - name: position dtype: - name: x dtype: float32 doc: x coordinate - name: y dtype: float32 doc: y coordinate - name: z dtype: float32 doc: z coordinate doc: stereotaxic or common framework coordinates quantity: '?' links: - name: device target_type: Device doc: Link to the device that was used to record from this electrode group. # The types below have been deprecated - neurodata_type_def: ClusterWaveforms neurodata_type_inc: NWBDataInterface default_name: ClusterWaveforms doc: DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one. datasets: - name: waveform_filtering dtype: text doc: Filtering applied to data before generating mean/sd - name: waveform_mean dtype: float32 dims: - num_clusters - num_samples shape: - null - null doc: The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled) - name: waveform_sd dtype: float32 dims: - num_clusters - num_samples shape: - null - null doc: Stdev of waveforms for each cluster, using the same indices as in mean links: - name: clustering_interface target_type: Clustering doc: Link to Clustering interface that was the source of the clustered data - neurodata_type_def: Clustering neurodata_type_inc: NWBDataInterface default_name: Clustering doc: DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting. datasets: - name: description dtype: text doc: Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc) - name: num dtype: int32 dims: - num_events shape: - null doc: Cluster number of each event - name: peak_over_rms dtype: float32 dims: - num_clusters shape: - null doc: Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric). - name: times dtype: float64 dims: - num_events shape: - null doc: Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.epoch.yaml0000644000175100001730000000162414467767510021753 0ustar00runnerdockergroups: - neurodata_type_def: TimeIntervals neurodata_type_inc: DynamicTable doc: A container for aggregating epoch data and the TimeSeries that each epoch applies to. datasets: - name: start_time neurodata_type_inc: VectorData dtype: float32 doc: Start time of epoch, in seconds. - name: stop_time neurodata_type_inc: VectorData dtype: float32 doc: Stop time of epoch, in seconds. - name: tags neurodata_type_inc: VectorData dtype: text doc: User-defined tags that identify or categorize events. quantity: '?' - name: tags_index neurodata_type_inc: VectorIndex doc: Index for tags. quantity: '?' - name: timeseries neurodata_type_inc: TimeSeriesReferenceVectorData doc: An index into a TimeSeries object. quantity: '?' - name: timeseries_index neurodata_type_inc: VectorIndex doc: Index for timeseries. quantity: '?' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.file.yaml0000644000175100001730000005204314467767510021575 0ustar00runnerdockergroups: - neurodata_type_def: NWBFile neurodata_type_inc: NWBContainer name: root doc: An NWB file storing cellular-based neurophysiology data from a single experimental session. attributes: - name: nwb_version dtype: text value: "2.6.0" doc: File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers. datasets: - name: file_create_date dtype: isodatetime dims: - num_modifications shape: - null doc: 'A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in "Z" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array.' - name: identifier dtype: text doc: A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files. - name: session_description dtype: text doc: A description of the experimental session and data in the file. - name: session_start_time dtype: isodatetime doc: 'Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in "Z" with no timezone offset. Date accuracy is up to milliseconds.' - name: timestamps_reference_time dtype: isodatetime doc: 'Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in "Z" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).' groups: - name: acquisition doc: Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis. groups: - neurodata_type_inc: NWBDataInterface doc: Acquired, raw data. quantity: '*' - neurodata_type_inc: DynamicTable doc: Tabular data that is relevent to acquisition quantity: '*' - name: analysis doc: Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs. groups: - neurodata_type_inc: NWBContainer doc: Custom analysis results. quantity: '*' - neurodata_type_inc: DynamicTable doc: Tabular data that is relevent to data stored in analysis quantity: '*' - name: scratch doc: 'A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.' quantity: '?' groups: - neurodata_type_inc: NWBContainer doc: Any one-off containers quantity: '*' - neurodata_type_inc: DynamicTable doc: Any one-off tables quantity: '*' datasets: - neurodata_type_inc: ScratchData doc: Any one-off datasets quantity: '*' - name: processing doc: "The home for ProcessingModules. These modules perform intermediate analysis\ \ of data that is necessary to perform before scientific analysis. Examples\ \ include spike clustering, extracting position from tracking data, stitching\ \ together image slices. ProcessingModules can be large\ \ and express many data sets from relatively complex analysis (e.g., spike detection\ \ and clustering) or small, representing extraction of position information\ \ from tracking video, or even binary lick/no-lick decisions. Common software\ \ tools (e.g., klustakwik, MClust) are expected to read/write data here. \ \ 'Processing' refers to intermediate analysis of the acquired data to make\ \ it more amenable to scientific analysis." groups: - neurodata_type_inc: ProcessingModule doc: Intermediate analysis of acquired data. quantity: '*' - name: stimulus doc: 'Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file.' groups: - name: presentation doc: Stimuli presented during the experiment. groups: - neurodata_type_inc: TimeSeries doc: TimeSeries objects containing data of presented stimuli. quantity: '*' - name: templates doc: 'Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.' groups: - neurodata_type_inc: TimeSeries doc: TimeSeries objects containing template data of presented stimuli. quantity: '*' - neurodata_type_inc: Images doc: Images objects containing images of presented stimuli. quantity: '*' - name: general doc: "Experimental metadata, including protocol, notes and description of hardware\ \ device(s). The metadata stored in this section should be used to\ \ describe the experiment. Metadata necessary for interpreting the data is stored\ \ with the data. General experimental metadata, including animal\ \ strain, experimental protocols, experimenter, devices, etc, are stored under\ \ 'general'. Core metadata (e.g., that required to interpret data fields) is\ \ stored with the data itself, and implicitly defined by the file specification\ \ (e.g., time is in seconds). The strategy used here for storing non-core metadata\ \ is to use free-form text fields, such as would appear in sentences or paragraphs\ \ from a Methods section. Metadata fields are text to enable them to be more\ \ general, for example to represent ranges instead of numerical values. Machine-readable\ \ metadata is stored as attributes to these free-form datasets. All entries\ \ in the below table are to be included when data is present. Unused groups\ \ (e.g., intracellular_ephys in an optophysiology experiment) should not be\ \ created unless there is data to store within them." datasets: - name: data_collection dtype: text doc: Notes about data collection and analysis. quantity: '?' - name: experiment_description dtype: text doc: General description of the experiment. quantity: '?' - name: experimenter dtype: text doc: Name of person(s) who performed the experiment. Can also specify roles of different people involved. quantity: '?' dims: - num_experimenters shape: - null - name: institution dtype: text doc: Institution(s) where experiment was performed. quantity: '?' - name: keywords dtype: text dims: - num_keywords shape: - null doc: Terms to search over. quantity: '?' - name: lab dtype: text doc: Laboratory where experiment was performed. quantity: '?' - name: notes dtype: text doc: Notes about the experiment. quantity: '?' - name: pharmacology dtype: text doc: Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc. quantity: '?' - name: protocol dtype: text doc: Experimental protocol, if applicable. e.g., include IACUC protocol number. quantity: '?' - name: related_publications dtype: text doc: Publication information. PMID, DOI, URL, etc. dims: - num_publications shape: - null quantity: '?' - name: session_id dtype: text doc: Lab-specific ID for the session. quantity: '?' - name: slices dtype: text doc: Description of slices, including information about preparation thickness, orientation, temperature, and bath solution. quantity: '?' - name: source_script dtype: text doc: Script file or link to public source code used to create this NWB file. quantity: '?' attributes: - name: file_name dtype: text doc: Name of script file. - name: stimulus dtype: text doc: Notes about stimuli, such as how and where they were presented. quantity: '?' - name: surgery dtype: text doc: Narrative description about surgery/surgeries, including date(s) and who performed surgery. quantity: '?' - name: virus dtype: text doc: Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc. quantity: '?' groups: - neurodata_type_inc: LabMetaData doc: Place-holder than can be extended so that lab-specific meta-data can be placed in /general. quantity: '*' - name: devices doc: Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc. quantity: '?' groups: - neurodata_type_inc: Device doc: Data acquisition devices. quantity: '*' - name: subject neurodata_type_inc: Subject doc: Information about the animal or person from which the data was measured. quantity: '?' - name: extracellular_ephys doc: Metadata related to extracellular electrophysiology. quantity: '?' groups: - neurodata_type_inc: ElectrodeGroup doc: Physical group of electrodes. quantity: '*' - name: electrodes neurodata_type_inc: DynamicTable doc: A table of all electrodes (i.e. channels) used for recording. quantity: '?' datasets: - name: x neurodata_type_inc: VectorData dtype: float32 doc: x coordinate of the channel location in the brain (+x is posterior). quantity: '?' - name: y neurodata_type_inc: VectorData dtype: float32 doc: y coordinate of the channel location in the brain (+y is inferior). quantity: '?' - name: z neurodata_type_inc: VectorData dtype: float32 doc: z coordinate of the channel location in the brain (+z is right). quantity: '?' - name: imp neurodata_type_inc: VectorData dtype: float32 doc: Impedance of the channel, in ohms. quantity: '?' - name: location neurodata_type_inc: VectorData dtype: text doc: Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible. - name: filtering neurodata_type_inc: VectorData dtype: text doc: Description of hardware filtering, including the filter name and frequency cutoffs. quantity: '?' - name: group neurodata_type_inc: VectorData dtype: target_type: ElectrodeGroup reftype: object doc: Reference to the ElectrodeGroup this electrode is a part of. - name: group_name neurodata_type_inc: VectorData dtype: text doc: Name of the ElectrodeGroup this electrode is a part of. - name: rel_x neurodata_type_inc: VectorData dtype: float32 doc: x coordinate in electrode group quantity: '?' - name: rel_y neurodata_type_inc: VectorData dtype: float32 doc: y coordinate in electrode group quantity: '?' - name: rel_z neurodata_type_inc: VectorData dtype: float32 doc: z coordinate in electrode group quantity: '?' - name: reference neurodata_type_inc: VectorData dtype: text doc: Description of the reference electrode and/or reference scheme used for this electrode, e.g., "stainless steel skull screw" or "online common average referencing". quantity: '?' - name: intracellular_ephys doc: Metadata related to intracellular electrophysiology. quantity: '?' datasets: - name: filtering dtype: text doc: '[DEPRECATED] Use IntracellularElectrode.filtering instead. Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.' quantity: '?' groups: - neurodata_type_inc: IntracellularElectrode doc: An intracellular electrode. quantity: '*' - name: sweep_table neurodata_type_inc: SweepTable doc: '[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tabels. Additional SequentialRecordingsTable, RepetitionsTable and ExperimentalConditions tables provide enhanced support for experiment metadata.' quantity: '?' - name: intracellular_recordings neurodata_type_inc: IntracellularRecordingsTable doc: A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response are recorded as as part of an experiment. In this case both, the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used. quantity: '?' - name: simultaneous_recordings neurodata_type_inc: SimultaneousRecordingsTable doc: A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes quantity: '?' - name: sequential_recordings neurodata_type_inc: SequentialRecordingsTable doc: A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where the a sequence of stimuli of the same type with varying parameters have been presented in a sequence. quantity: '?' - name: repetitions neurodata_type_inc: RepetitionsTable doc: A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence. quantity: '?' - name: experimental_conditions neurodata_type_inc: ExperimentalConditionsTable doc: A table for grouping different intracellular recording repetitions together that belong to the same experimental experimental_conditions. quantity: '?' - name: optogenetics doc: Metadata describing optogenetic stimuluation. quantity: '?' groups: - neurodata_type_inc: OptogeneticStimulusSite doc: An optogenetic stimulation site. quantity: '*' - name: optophysiology doc: Metadata related to optophysiology. quantity: '?' groups: - neurodata_type_inc: ImagingPlane doc: An imaging plane. quantity: '*' - name: intervals doc: Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data. quantity: '?' groups: - name: epochs neurodata_type_inc: TimeIntervals doc: Divisions in time marking experimental stages or sub-divisions of a single recording session. quantity: '?' - name: trials neurodata_type_inc: TimeIntervals doc: Repeated experimental events that have a logical grouping. quantity: '?' - name: invalid_times neurodata_type_inc: TimeIntervals doc: Time intervals that should be removed from analysis. quantity: '?' - neurodata_type_inc: TimeIntervals doc: Optional additional table(s) for describing other experimental time intervals. quantity: '*' - name: units neurodata_type_inc: Units doc: Data about sorted spike units. quantity: '?' - neurodata_type_def: LabMetaData neurodata_type_inc: NWBContainer doc: Lab-specific meta-data. - neurodata_type_def: Subject neurodata_type_inc: NWBContainer doc: Information about the animal or person from which the data was measured. datasets: - name: age dtype: text doc: Age of subject. Can be supplied instead of 'date_of_birth'. quantity: '?' attributes: - name: reference doc: "Age is with reference to this event. Can be 'birth' or 'gestational'. If reference is omitted, 'birth' is implied." dtype: text required: false default_value: birth - name: date_of_birth dtype: isodatetime doc: Date of birth of subject. Can be supplied instead of 'age'. quantity: '?' - name: description dtype: text doc: Description of subject and where subject came from (e.g., breeder, if animal). quantity: '?' - name: genotype dtype: text doc: Genetic strain. If absent, assume Wild Type (WT). quantity: '?' - name: sex dtype: text doc: Gender of subject. quantity: '?' - name: species dtype: text doc: Species of subject. quantity: '?' - name: strain dtype: text doc: Strain of subject. quantity: '?' - name: subject_id dtype: text doc: ID of animal/person used/participating in experiment (lab convention). quantity: '?' - name: weight dtype: text doc: Weight at time of experiment, at time of surgery and at other important times. quantity: '?' datasets: - neurodata_type_def: ScratchData neurodata_type_inc: NWBData doc: Any one-off datasets attributes: - name: notes doc: 'Any notes the user has about the dataset being stored' dtype: text ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.icephys.yaml0000644000175100001730000003752414467767510022331 0ustar00runnerdockergroups: - neurodata_type_def: PatchClampSeries neurodata_type_inc: TimeSeries doc: An abstract base class for patch-clamp data - stimulus or response, current or voltage. attributes: - name: stimulus_description dtype: text doc: Protocol/stimulus name for this patch-clamp dataset. - name: sweep_number dtype: uint32 doc: Sweep number, allows to group different PatchClampSeries together. required: false datasets: - name: data dtype: numeric dims: - num_times shape: - null doc: Recorded voltage or current. attributes: - name: unit dtype: text doc: Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'. - name: gain dtype: float32 doc: Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp). quantity: '?' links: - name: electrode target_type: IntracellularElectrode doc: Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data. - neurodata_type_def: CurrentClampSeries neurodata_type_inc: PatchClampSeries doc: Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected. datasets: - name: data doc: Recorded voltage. attributes: - name: unit dtype: text value: volts doc: Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'. - name: bias_current dtype: float32 doc: Bias current, in amps. quantity: '?' - name: bridge_balance dtype: float32 doc: Bridge balance, in ohms. quantity: '?' - name: capacitance_compensation dtype: float32 doc: Capacitance compensation, in farads. quantity: '?' - neurodata_type_def: IZeroClampSeries neurodata_type_inc: CurrentClampSeries doc: Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell. attributes: - name: stimulus_description dtype: text doc: An IZeroClampSeries has no stimulus, so this attribute is automatically set to "N/A" value: N/A datasets: - name: bias_current dtype: float32 value: 0.0 doc: Bias current, in amps, fixed to 0.0. - name: bridge_balance dtype: float32 value: 0.0 doc: Bridge balance, in ohms, fixed to 0.0. - name: capacitance_compensation dtype: float32 value: 0.0 doc: Capacitance compensation, in farads, fixed to 0.0. - neurodata_type_def: CurrentClampStimulusSeries neurodata_type_inc: PatchClampSeries doc: Stimulus current applied during current clamp recording. datasets: - name: data doc: Stimulus current applied. attributes: - name: unit dtype: text value: amperes doc: Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'. - neurodata_type_def: VoltageClampSeries neurodata_type_inc: PatchClampSeries doc: Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected. datasets: - name: data doc: Recorded current. attributes: - name: unit dtype: text value: amperes doc: Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'. - name: capacitance_fast dtype: float32 doc: Fast capacitance, in farads. quantity: '?' attributes: - name: unit dtype: text value: farads doc: Unit of measurement for capacitance_fast, which is fixed to 'farads'. - name: capacitance_slow dtype: float32 doc: Slow capacitance, in farads. quantity: '?' attributes: - name: unit dtype: text value: farads doc: Unit of measurement for capacitance_fast, which is fixed to 'farads'. - name: resistance_comp_bandwidth dtype: float32 doc: Resistance compensation bandwidth, in hertz. quantity: '?' attributes: - name: unit dtype: text value: hertz doc: Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'. - name: resistance_comp_correction dtype: float32 doc: Resistance compensation correction, in percent. quantity: '?' attributes: - name: unit dtype: text value: percent doc: Unit of measurement for resistance_comp_correction, which is fixed to 'percent'. - name: resistance_comp_prediction dtype: float32 doc: Resistance compensation prediction, in percent. quantity: '?' attributes: - name: unit dtype: text value: percent doc: Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'. - name: whole_cell_capacitance_comp dtype: float32 doc: Whole cell capacitance compensation, in farads. quantity: '?' attributes: - name: unit dtype: text value: farads doc: Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'. - name: whole_cell_series_resistance_comp dtype: float32 doc: Whole cell series resistance compensation, in ohms. quantity: '?' attributes: - name: unit dtype: text value: ohms doc: Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'. - neurodata_type_def: VoltageClampStimulusSeries neurodata_type_inc: PatchClampSeries doc: Stimulus voltage applied during a voltage clamp recording. datasets: - name: data doc: Stimulus voltage applied. attributes: - name: unit dtype: text value: volts doc: Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'. - neurodata_type_def: IntracellularElectrode neurodata_type_inc: NWBContainer doc: An intracellular electrode and its metadata. datasets: - name: cell_id dtype: text doc: unique ID of the cell quantity: '?' - name: description dtype: text doc: Description of electrode (e.g., whole-cell, sharp, etc.). - name: filtering dtype: text doc: Electrode specific filtering. quantity: '?' - name: initial_access_resistance dtype: text doc: Initial access resistance. quantity: '?' - name: location dtype: text doc: Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible. quantity: '?' - name: resistance dtype: text doc: Electrode resistance, in ohms. quantity: '?' - name: seal dtype: text doc: Information about seal used for recording. quantity: '?' - name: slice dtype: text doc: Information about slice used for recording. quantity: '?' links: - name: device target_type: Device doc: Device that was used to record from this electrode. - neurodata_type_def: SweepTable neurodata_type_inc: DynamicTable doc: '[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tables. Additional SequentialRecordingsTable, RepetitionsTable, and ExperimentalConditions tables provide enhanced support for experiment metadata.' datasets: - name: sweep_number neurodata_type_inc: VectorData dtype: uint32 doc: Sweep number of the PatchClampSeries in that row. - name: series neurodata_type_inc: VectorData dtype: target_type: PatchClampSeries reftype: object doc: The PatchClampSeries with the sweep number in that row. - name: series_index neurodata_type_inc: VectorIndex doc: Index for series. - neurodata_type_def: IntracellularElectrodesTable neurodata_type_inc: DynamicTable doc: Table for storing intracellular electrode related metadata. attributes: - name: description dtype: text value: Table for storing intracellular electrode related metadata. doc: Description of what is in this dynamic table. datasets: - name: electrode neurodata_type_inc: VectorData dtype: target_type: IntracellularElectrode reftype: object doc: Column for storing the reference to the intracellular electrode. - neurodata_type_def: IntracellularStimuliTable neurodata_type_inc: DynamicTable doc: Table for storing intracellular stimulus related metadata. attributes: - name: description dtype: text value: Table for storing intracellular stimulus related metadata. doc: Description of what is in this dynamic table. datasets: - name: stimulus neurodata_type_inc: TimeSeriesReferenceVectorData doc: Column storing the reference to the recorded stimulus for the recording (rows). - neurodata_type_def: IntracellularResponsesTable neurodata_type_inc: DynamicTable doc: Table for storing intracellular response related metadata. attributes: - name: description dtype: text value: Table for storing intracellular response related metadata. doc: Description of what is in this dynamic table. datasets: - name: response neurodata_type_inc: TimeSeriesReferenceVectorData doc: Column storing the reference to the recorded response for the recording (rows) - neurodata_type_def: IntracellularRecordingsTable neurodata_type_inc: AlignedDynamicTable name: intracellular_recordings doc: A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response is recorded as part of an experiment. In this case, both the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used. attributes: - name: description dtype: text value: A table to group together a stimulus and response from a single electrode and a single simultaneous recording and for storing metadata about the intracellular recording. doc: Description of the contents of this table. Inherited from AlignedDynamicTable and overwritten here to fix the value of the attribute. groups: - name: electrodes neurodata_type_inc: IntracellularElectrodesTable doc: Table for storing intracellular electrode related metadata. - name: stimuli neurodata_type_inc: IntracellularStimuliTable doc: Table for storing intracellular stimulus related metadata. - name: responses neurodata_type_inc: IntracellularResponsesTable doc: Table for storing intracellular response related metadata. - neurodata_type_def: SimultaneousRecordingsTable neurodata_type_inc: DynamicTable name: simultaneous_recordings doc: A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes. datasets: - name: recordings neurodata_type_inc: DynamicTableRegion doc: A reference to one or more rows in the IntracellularRecordingsTable table. attributes: - name: table dtype: target_type: IntracellularRecordingsTable reftype: object doc: Reference to the IntracellularRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here. - name: recordings_index neurodata_type_inc: VectorIndex doc: Index dataset for the recordings column. - neurodata_type_def: SequentialRecordingsTable neurodata_type_inc: DynamicTable name: sequential_recordings doc: A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where a sequence of stimuli of the same type with varying parameters have been presented in a sequence. datasets: - name: simultaneous_recordings neurodata_type_inc: DynamicTableRegion doc: A reference to one or more rows in the SimultaneousRecordingsTable table. attributes: - name: table dtype: target_type: SimultaneousRecordingsTable reftype: object doc: Reference to the SimultaneousRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here. - name: simultaneous_recordings_index neurodata_type_inc: VectorIndex doc: Index dataset for the simultaneous_recordings column. - name: stimulus_type neurodata_type_inc: VectorData dtype: text doc: The type of stimulus used for the sequential recording. - neurodata_type_def: RepetitionsTable neurodata_type_inc: DynamicTable name: repetitions doc: A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence. datasets: - name: sequential_recordings neurodata_type_inc: DynamicTableRegion doc: A reference to one or more rows in the SequentialRecordingsTable table. attributes: - name: table dtype: target_type: SequentialRecordingsTable reftype: object doc: Reference to the SequentialRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here. - name: sequential_recordings_index neurodata_type_inc: VectorIndex doc: Index dataset for the sequential_recordings column. - neurodata_type_def: ExperimentalConditionsTable neurodata_type_inc: DynamicTable name: experimental_conditions doc: A table for grouping different intracellular recording repetitions together that belong to the same experimental condition. datasets: - name: repetitions neurodata_type_inc: DynamicTableRegion doc: A reference to one or more rows in the RepetitionsTable table. attributes: - name: table dtype: target_type: RepetitionsTable reftype: object doc: Reference to the RepetitionsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here. - name: repetitions_index neurodata_type_inc: VectorIndex doc: Index dataset for the repetitions column. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.image.yaml0000644000175100001730000001604114467767510021736 0ustar00runnerdockerdatasets: - neurodata_type_def: GrayscaleImage neurodata_type_inc: Image dims: - x - y shape: - null - null doc: A grayscale image. dtype: numeric - neurodata_type_def: RGBImage neurodata_type_inc: Image dims: - x - y - r, g, b shape: - null - null - 3 doc: A color image. dtype: numeric - neurodata_type_def: RGBAImage neurodata_type_inc: Image dims: - x - y - r, g, b, a shape: - null - null - 4 doc: A color image with transparency. dtype: numeric groups: - neurodata_type_def: ImageSeries neurodata_type_inc: TimeSeries doc: General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][x][y] or [frame][x][y][z]. datasets: - name: data dtype: numeric dims: - - frame - x - y - - frame - x - y - z shape: - - null - null - null - - null - null - null - null doc: Binary data representing images across frames. If data are stored in an external file, this should be an empty 3D array. - name: dimension dtype: int32 dims: - rank shape: - null doc: Number of pixels on x, y, (and z) axes. quantity: '?' - name: external_file dtype: text dims: - num_files shape: - null doc: Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file. quantity: '?' attributes: - name: starting_frame dtype: int32 dims: - num_files shape: - null doc: Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0]. - name: format dtype: text default_value: raw doc: Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed. quantity: '?' links: - name: device target_type: Device doc: Link to the Device object that was used to capture these images. quantity: '?' - neurodata_type_def: ImageMaskSeries neurodata_type_inc: ImageSeries doc: An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed. links: - name: masked_imageseries target_type: ImageSeries doc: Link to ImageSeries object that this image mask is applied to. - neurodata_type_def: OpticalSeries neurodata_type_inc: ImageSeries doc: Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important. datasets: - name: distance dtype: float32 doc: Distance from camera/monitor to target/eye. quantity: '?' - name: field_of_view dtype: float32 dims: - - width, height - - width, height, depth shape: - - 2 - - 3 doc: Width, height and depth of image, or imaged area, in meters. quantity: '?' - name: data dtype: numeric dims: - - frame - x - y - - frame - x - y - r, g, b shape: - - null - null - null - - null - null - null - 3 doc: Images presented to subject, either grayscale or RGB - name: orientation dtype: text doc: Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference. quantity: '?' - neurodata_type_def: IndexSeries neurodata_type_inc: TimeSeries doc: Stores indices to image frames stored in an ImageSeries. The purpose of the IndexSeries is to allow a static image stack to be stored in an Images object, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced Images object, and the timestamps array indicates when that image was displayed. datasets: - name: data dtype: uint32 dims: - num_times shape: - null doc: Index of the image (using zero-indexing) in the linked Images object. attributes: - name: conversion dtype: float32 doc: This field is unused by IndexSeries. required: false - name: resolution dtype: float32 doc: This field is unused by IndexSeries. required: false - name: offset dtype: float32 doc: This field is unused by IndexSeries. required: false - name: unit dtype: text value: N/A doc: This field is unused by IndexSeries and has the value N/A. links: - name: indexed_timeseries target_type: ImageSeries doc: Link to ImageSeries object containing images that are indexed. Use of this link is discouraged and will be deprecated. Link to an Images type instead. quantity: '?' - name: indexed_images target_type: Images doc: Link to Images object containing an ordered set of images that are indexed. The Images object must contain a 'ordered_images' dataset specifying the order of the images in the Images type. quantity: '?' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.misc.yaml0000644000175100001730000002657214467767510021621 0ustar00runnerdockergroups: - neurodata_type_def: AbstractFeatureSeries neurodata_type_inc: TimeSeries doc: Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical. datasets: - name: data dtype: numeric dims: - - num_times - - num_times - num_features shape: - - null - - null - null doc: Values of each feature at each time. attributes: - name: unit dtype: text default_value: see 'feature_units' doc: Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is "see 'feature_units'". required: false - name: feature_units dtype: text dims: - num_features shape: - null doc: Units of each feature. quantity: '?' - name: features dtype: text dims: - num_features shape: - null doc: Description of the features represented in TimeSeries::data. - neurodata_type_def: AnnotationSeries neurodata_type_inc: TimeSeries doc: Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way. datasets: - name: data dtype: text dims: - num_times shape: - null doc: Annotations made during an experiment. attributes: - name: resolution dtype: float32 value: -1.0 doc: Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0. - name: unit dtype: text value: n/a doc: Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'. - neurodata_type_def: IntervalSeries neurodata_type_inc: TimeSeries doc: Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way. datasets: - name: data dtype: int8 dims: - num_times shape: - null doc: Use values >0 if interval started, <0 if interval ended. attributes: - name: resolution dtype: float32 value: -1.0 doc: Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0. - name: unit dtype: text value: n/a doc: Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'. - neurodata_type_def: DecompositionSeries neurodata_type_inc: TimeSeries doc: Spectral analysis of a time series, e.g. of an LFP or a speech signal. datasets: - name: data dtype: numeric dims: - num_times - num_channels - num_bands shape: - null - null - null doc: Data decomposed into frequency bands. attributes: - name: unit dtype: text default_value: no unit doc: Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'. - name: metric dtype: text doc: The metric used, e.g. phase, amplitude, power. - name: source_channels neurodata_type_inc: DynamicTableRegion doc: DynamicTableRegion pointer to the channels that this decomposition series was generated from. quantity: '?' groups: - name: bands neurodata_type_inc: DynamicTable doc: Table for describing the bands that this series was generated from. There should be one row in this table for each band. datasets: - name: band_name neurodata_type_inc: VectorData dtype: text doc: Name of the band, e.g. theta. - name: band_limits neurodata_type_inc: VectorData dtype: float32 dims: - num_bands - low, high shape: - null - 2 doc: Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center. - name: band_mean neurodata_type_inc: VectorData dtype: float32 dims: - num_bands shape: - null doc: The mean Gaussian filters, in Hz. - name: band_stdev neurodata_type_inc: VectorData dtype: float32 dims: - num_bands shape: - null doc: The standard deviation of Gaussian filters, in Hz. links: - name: source_timeseries target_type: TimeSeries doc: Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here. quantity: '?' - neurodata_type_def: Units neurodata_type_inc: DynamicTable default_name: Units doc: Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times. datasets: - name: spike_times_index neurodata_type_inc: VectorIndex doc: Index into the spike_times dataset. quantity: '?' - name: spike_times neurodata_type_inc: VectorData dtype: float64 doc: Spike times for each unit in seconds. quantity: '?' attributes: - name: resolution dtype: float64 doc: The smallest possible difference between two spike times. Usually 1 divided by the acquisition sampling rate from which spike times were extracted, but could be larger if the acquisition time series was downsampled or smaller if the acquisition time series was smoothed/interpolated and it is possible for the spike time to be between samples. required: false - name: obs_intervals_index neurodata_type_inc: VectorIndex doc: Index into the obs_intervals dataset. quantity: '?' - name: obs_intervals neurodata_type_inc: VectorData dtype: float64 dims: - num_intervals - start|end shape: - null - 2 doc: Observation intervals for each unit. quantity: '?' - name: electrodes_index neurodata_type_inc: VectorIndex doc: Index into electrodes. quantity: '?' - name: electrodes neurodata_type_inc: DynamicTableRegion doc: Electrode that each spike unit came from, specified using a DynamicTableRegion. quantity: '?' - name: electrode_group neurodata_type_inc: VectorData dtype: target_type: ElectrodeGroup reftype: object doc: Electrode group that each spike unit came from. quantity: '?' - name: waveform_mean neurodata_type_inc: VectorData dtype: float32 dims: - - num_units - num_samples - - num_units - num_samples - num_electrodes shape: - - null - null - - null - null - null doc: Spike waveform mean for each spike unit. quantity: '?' attributes: - name: sampling_rate dtype: float32 doc: Sampling rate, in hertz. required: false - name: unit dtype: text value: volts doc: Unit of measurement. This value is fixed to 'volts'. required: false - name: waveform_sd neurodata_type_inc: VectorData dtype: float32 dims: - - num_units - num_samples - - num_units - num_samples - num_electrodes shape: - - null - null - - null - null - null doc: Spike waveform standard deviation for each spike unit. quantity: '?' attributes: - name: sampling_rate dtype: float32 doc: Sampling rate, in hertz. required: false - name: unit dtype: text value: volts doc: Unit of measurement. This value is fixed to 'volts'. required: false - name: waveforms neurodata_type_inc: VectorData dtype: numeric dims: - num_waveforms - num_samples shape: - null - null doc: "Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same." quantity: '?' attributes: - name: sampling_rate dtype: float32 doc: Sampling rate, in hertz. required: false - name: unit dtype: text value: volts doc: Unit of measurement. This value is fixed to 'volts'. required: false - name: waveforms_index neurodata_type_inc: VectorIndex doc: Index into the waveforms dataset. One value for every spike event. See 'waveforms' for more detail. quantity: '?' - name: waveforms_index_index neurodata_type_inc: VectorIndex doc: Index into the waveforms_index dataset. One value for every unit (row in the table). See 'waveforms' for more detail. quantity: '?' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.namespace.yaml0000644000175100001730000000360314467767510022610 0ustar00runnerdockernamespaces: - name: core doc: NWB namespace author: - Andrew Tritt - Oliver Ruebel - Ryan Ly - Ben Dichter - Keith Godfrey - Jeff Teeters contact: - ajtritt@lbl.gov - oruebel@lbl.gov - rly@lbl.gov - bdichter@lbl.gov - keithg@alleninstitute.org - jteeters@berkeley.edu full_name: NWB core schema: - namespace: hdmf-common - doc: This source module contains base data types used throughout the NWB data format. source: nwb.base.yaml title: Base data types - doc: This source module contains neurodata_types for device data. source: nwb.device.yaml title: Devices - doc: This source module contains neurodata_types for epoch data. source: nwb.epoch.yaml title: Epochs - doc: This source module contains neurodata_types for image data. source: nwb.image.yaml title: Image data - doc: Main NWB file specification. source: nwb.file.yaml title: NWB file - doc: Miscellaneous types. source: nwb.misc.yaml title: Miscellaneous neurodata_types. - doc: This source module contains neurodata_types for behavior data. source: nwb.behavior.yaml title: Behavior - doc: This source module contains neurodata_types for extracellular electrophysiology data. source: nwb.ecephys.yaml title: Extracellular electrophysiology - doc: This source module contains neurodata_types for intracellular electrophysiology data. source: nwb.icephys.yaml title: Intracellular electrophysiology - doc: This source module contains neurodata_types for opto-genetics data. source: nwb.ogen.yaml title: Optogenetics - doc: This source module contains neurodata_types for optical physiology data. source: nwb.ophys.yaml title: Optical physiology - doc: This source module contains neurodata_type for retinotopy data. source: nwb.retinotopy.yaml title: Retinotopy version: "2.6.0-alpha" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.ogen.yaml0000644000175100001730000000232514467767510021604 0ustar00runnerdockergroups: - neurodata_type_def: OptogeneticSeries neurodata_type_inc: TimeSeries doc: An optogenetic stimulus. datasets: - name: data dtype: numeric dims: - num_times shape: - null doc: Applied power for optogenetic stimulus, in watts. attributes: - name: unit dtype: text value: watts doc: Unit of measurement for data, which is fixed to 'watts'. links: - name: site target_type: OptogeneticStimulusSite doc: Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied. - neurodata_type_def: OptogeneticStimulusSite neurodata_type_inc: NWBContainer doc: A site of optogenetic stimulation. datasets: - name: description dtype: text doc: Description of stimulation site. - name: excitation_lambda dtype: float32 doc: Excitation wavelength, in nm. - name: location dtype: text doc: Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible. links: - name: device target_type: Device doc: Device that generated the stimulus. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.ophys.yaml0000644000175100001730000003065214467767510022022 0ustar00runnerdockergroups: - neurodata_type_def: OnePhotonSeries neurodata_type_inc: ImageSeries doc: Image stack recorded over time from 1-photon microscope. attributes: - name: pmt_gain dtype: float32 doc: Photomultiplier gain. required: false - name: scan_line_rate dtype: float32 doc: Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data. required: false - name: exposure_time dtype: float32 doc: Exposure time of the sample; often the inverse of the frequency. required: false - name: binning dtype: uint8 doc: Amount of pixels combined into 'bins'; could be 1, 2, 4, 8, etc. required: false - name: power dtype: float32 doc: Power of the excitation in mW, if known. required: false - name: intensity dtype: float32 doc: Intensity of the excitation in mW/mm^2, if known. required: false links: - name: imaging_plane target_type: ImagingPlane doc: Link to ImagingPlane object from which this TimeSeries data was generated. - neurodata_type_def: TwoPhotonSeries neurodata_type_inc: ImageSeries doc: Image stack recorded over time from 2-photon microscope. attributes: - name: pmt_gain dtype: float32 doc: Photomultiplier gain. required: false - name: scan_line_rate dtype: float32 doc: Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data. required: false datasets: - name: field_of_view dtype: float32 dims: - - width|height - - width|height|depth shape: - - 2 - - 3 doc: Width, height and depth of image, or imaged area, in meters. quantity: '?' links: - name: imaging_plane target_type: ImagingPlane doc: Link to ImagingPlane object from which this TimeSeries data was generated. - neurodata_type_def: RoiResponseSeries neurodata_type_inc: TimeSeries doc: ROI responses over an imaging plane. The first dimension represents time. The second dimension, if present, represents ROIs. datasets: - name: data dtype: numeric dims: - - num_times - - num_times - num_ROIs shape: - - null - - null - null doc: Signals from ROIs. - name: rois neurodata_type_inc: DynamicTableRegion doc: DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries. - neurodata_type_def: DfOverF neurodata_type_inc: NWBDataInterface default_name: DfOverF doc: dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes). groups: - neurodata_type_inc: RoiResponseSeries doc: RoiResponseSeries object(s) containing dF/F for a ROI. quantity: '+' - neurodata_type_def: Fluorescence neurodata_type_inc: NWBDataInterface default_name: Fluorescence doc: Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes). groups: - neurodata_type_inc: RoiResponseSeries doc: RoiResponseSeries object(s) containing fluorescence data for a ROI. quantity: '+' - neurodata_type_def: ImageSegmentation neurodata_type_inc: NWBDataInterface default_name: ImageSegmentation doc: Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them. groups: - neurodata_type_inc: PlaneSegmentation doc: Results from image segmentation of a specific imaging plane. quantity: '+' - neurodata_type_def: PlaneSegmentation neurodata_type_inc: DynamicTable doc: Results from image segmentation of a specific imaging plane. datasets: - name: image_mask neurodata_type_inc: VectorData dims: - - num_roi - num_x - num_y - - num_roi - num_x - num_y - num_z shape: - - null - null - null - - null - null - null - null doc: ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero. quantity: '?' - name: pixel_mask_index neurodata_type_inc: VectorIndex doc: Index into pixel_mask. quantity: '?' - name: pixel_mask neurodata_type_inc: VectorData dtype: - name: x dtype: uint32 doc: Pixel x-coordinate. - name: y dtype: uint32 doc: Pixel y-coordinate. - name: weight dtype: float32 doc: Weight of the pixel. doc: 'Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation' quantity: '?' - name: voxel_mask_index neurodata_type_inc: VectorIndex doc: Index into voxel_mask. quantity: '?' - name: voxel_mask neurodata_type_inc: VectorData dtype: - name: x dtype: uint32 doc: Voxel x-coordinate. - name: y dtype: uint32 doc: Voxel y-coordinate. - name: z dtype: uint32 doc: Voxel z-coordinate. - name: weight dtype: float32 doc: Weight of the voxel. doc: 'Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation' quantity: '?' groups: - name: reference_images doc: Image stacks that the segmentation masks apply to. groups: - neurodata_type_inc: ImageSeries doc: One or more image stacks that the masks apply to (can be one-element stack). quantity: '*' links: - name: imaging_plane target_type: ImagingPlane doc: Link to ImagingPlane object from which this data was generated. - neurodata_type_def: ImagingPlane neurodata_type_inc: NWBContainer doc: An imaging plane and its metadata. datasets: - name: description dtype: text doc: Description of the imaging plane. quantity: '?' - name: excitation_lambda dtype: float32 doc: Excitation wavelength, in nm. - name: imaging_rate dtype: float32 doc: Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead. quantity: '?' - name: indicator dtype: text doc: Calcium indicator. - name: location dtype: text doc: Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible. - name: manifold dtype: float32 dims: - - height - width - x, y, z - - height - width - depth - x, y, z shape: - - null - null - 3 - - null - null - null - 3 doc: "DEPRECATED Physical position of each pixel. 'xyz' represents the position\ \ of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing." quantity: '?' attributes: - name: conversion dtype: float32 default_value: 1.0 doc: Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000. required: false - name: unit dtype: text default_value: meters doc: Base unit of measurement for working with the data. The default value is 'meters'. required: false - name: origin_coords dtype: float32 dims: - - x, y - - x, y, z shape: - - 2 - - 3 doc: Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma). quantity: '?' attributes: - name: unit dtype: text default_value: meters doc: Measurement units for origin_coords. The default value is 'meters'. - name: grid_spacing dtype: float32 dims: - - x, y - - x, y, z shape: - - 2 - - 3 doc: Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid. quantity: '?' attributes: - name: unit dtype: text default_value: meters doc: Measurement units for grid_spacing. The default value is 'meters'. - name: reference_frame dtype: text doc: Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = "Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral)." quantity: '?' groups: - neurodata_type_inc: OpticalChannel doc: An optical channel used to record from an imaging plane. quantity: '+' links: - name: device target_type: Device doc: Link to the Device object that was used to record from this electrode. - neurodata_type_def: OpticalChannel neurodata_type_inc: NWBContainer doc: An optical channel used to record from an imaging plane. datasets: - name: description dtype: text doc: Description or other notes about the channel. - name: emission_lambda dtype: float32 doc: Emission wavelength for channel, in nm. - neurodata_type_def: MotionCorrection neurodata_type_inc: NWBDataInterface default_name: MotionCorrection doc: 'An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).' groups: - neurodata_type_inc: CorrectedImageStack doc: Reuslts from motion correction of an image stack. quantity: '+' - neurodata_type_def: CorrectedImageStack neurodata_type_inc: NWBDataInterface doc: Reuslts from motion correction of an image stack. groups: - name: corrected neurodata_type_inc: ImageSeries doc: Image stack with frames shifted to the common coordinates. - name: xy_translation neurodata_type_inc: TimeSeries doc: Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image. links: - name: original target_type: ImageSeries doc: Link to ImageSeries object that is being registered. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397384.0 pynwb-2.5.0/src/pynwb/nwb-schema/core/nwb.retinotopy.yaml0000644000175100001730000001460114467767510023070 0ustar00runnerdockergroups: - neurodata_type_def: ImagingRetinotopy neurodata_type_inc: NWBDataInterface default_name: ImagingRetinotopy doc: 'Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. This group does not store the raw responses imaged during retinotopic mapping or the stimuli presented, but rather the resulting phase and power maps after applying a Fourier transform on the averaged responses. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).' datasets: - name: axis_1_phase_map dtype: float32 dims: - num_rows - num_cols shape: - null - null doc: Phase response to stimulus on the first measured axis. attributes: - name: dimension dtype: int32 dims: - num_rows, num_cols shape: - 2 doc: 'Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.' - name: field_of_view dtype: float32 dims: - height, width shape: - 2 doc: Size of viewing area, in meters. - name: unit dtype: text doc: Unit that axis data is stored in (e.g., degrees). - name: axis_1_power_map dtype: float32 dims: - num_rows - num_cols shape: - null - null doc: Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power. quantity: '?' attributes: - name: dimension dtype: int32 dims: - num_rows, num_cols shape: - 2 doc: 'Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.' - name: field_of_view dtype: float32 dims: - height, width shape: - 2 doc: Size of viewing area, in meters. - name: unit dtype: text doc: Unit that axis data is stored in (e.g., degrees). - name: axis_2_phase_map dtype: float32 dims: - num_rows - num_cols shape: - null - null doc: Phase response to stimulus on the second measured axis. attributes: - name: dimension dtype: int32 dims: - num_rows, num_cols shape: - 2 doc: 'Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.' - name: field_of_view dtype: float32 dims: - height, width shape: - 2 doc: Size of viewing area, in meters. - name: unit dtype: text doc: Unit that axis data is stored in (e.g., degrees). - name: axis_2_power_map dtype: float32 dims: - num_rows - num_cols shape: - null - null doc: Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power. quantity: '?' attributes: - name: dimension dtype: int32 dims: - num_rows, num_cols shape: - 2 doc: 'Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.' - name: field_of_view dtype: float32 dims: - height, width shape: - 2 doc: Size of viewing area, in meters. - name: unit dtype: text doc: Unit that axis data is stored in (e.g., degrees). - name: axis_descriptions dtype: text dims: - axis_1, axis_2 shape: - 2 doc: Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta']. - name: focal_depth_image dtype: uint16 dims: - num_rows - num_cols shape: - null - null doc: 'Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].' quantity: '?' attributes: - name: bits_per_pixel dtype: int32 doc: Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value. - name: dimension dtype: int32 dims: - num_rows, num_cols shape: - 2 doc: 'Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.' - name: field_of_view dtype: float32 dims: - height, width shape: - 2 doc: Size of viewing area, in meters. - name: focal_depth dtype: float32 doc: Focal depth offset, in meters. - name: format dtype: text doc: Format of image. Right now only 'raw' is supported. - name: sign_map dtype: float32 dims: - num_rows - num_cols shape: - null - null doc: Sine of the angle between the direction of the gradient in axis_1 and axis_2. quantity: '?' attributes: - name: dimension dtype: int32 dims: - num_rows, num_cols shape: - 2 doc: 'Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.' - name: field_of_view dtype: float32 dims: - height, width shape: - 2 doc: Size of viewing area, in meters. - name: vasculature_image dtype: uint16 dims: - num_rows - num_cols shape: - null - null doc: 'Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]' attributes: - name: bits_per_pixel dtype: int32 doc: Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value - name: dimension dtype: int32 dims: - num_rows, num_cols shape: - 2 doc: 'Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.' - name: field_of_view dtype: float32 dims: - height, width shape: - 2 doc: Size of viewing area, in meters. - name: format dtype: text doc: Format of image. Right now only 'raw' is supported. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/ogen.py0000644000175100001730000000412314467767506015534 0ustar00runnerdockerfrom hdmf.utils import docval, popargs, get_docval, popargs_to_dict from . import register_class, CORE_NAMESPACE from .base import TimeSeries from .core import NWBContainer from .device import Device @register_class('OptogeneticStimulusSite', CORE_NAMESPACE) class OptogeneticStimulusSite(NWBContainer): """Optogenetic stimulus site.""" __nwbfields__ = ('device', 'description', 'excitation_lambda', 'location') @docval({'name': 'name', 'type': str, 'doc': 'The name of this stimulus site.'}, {'name': 'device', 'type': Device, 'doc': 'The device that was used.'}, {'name': 'description', 'type': str, 'doc': 'Description of site.'}, {'name': 'excitation_lambda', 'type': float, 'doc': 'Excitation wavelength in nm.'}, {'name': 'location', 'type': str, 'doc': 'Location of stimulation site.'}) def __init__(self, **kwargs): args_to_set = popargs_to_dict(('device', 'description', 'excitation_lambda', 'location'), kwargs) super().__init__(**kwargs) for key, val in args_to_set.items(): setattr(self, key, val) @register_class('OptogeneticSeries', CORE_NAMESPACE) class OptogeneticSeries(TimeSeries): ''' Optogenetic stimulus. The data field is in unit of watts. ''' __nwbfields__ = ('site',) @docval(*get_docval(TimeSeries.__init__, 'name'), # required {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': (None, ), # required 'doc': 'The data values over time. Must be 1D.'}, {'name': 'site', 'type': OptogeneticStimulusSite, # required 'doc': 'The site to which this stimulus was applied.'}, *get_docval(TimeSeries.__init__, 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'offset')) def __init__(self, **kwargs): site = popargs('site', kwargs) kwargs['unit'] = 'watts' super().__init__(**kwargs) self.site = site ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/ophys.py0000644000175100001730000005424414467767506015757 0ustar00runnerdockerfrom collections.abc import Iterable import numpy as np import warnings from hdmf.common import DynamicTable, DynamicTableRegion from hdmf.utils import docval, popargs, get_docval, get_data_shape, popargs_to_dict from . import register_class, CORE_NAMESPACE from .base import TimeSeries from .image import ImageSeries from .core import NWBContainer, MultiContainerInterface, NWBDataInterface from .device import Device @register_class('OpticalChannel', CORE_NAMESPACE) class OpticalChannel(NWBContainer): """An optical channel used to record from an imaging plane.""" __nwbfields__ = ('description', 'emission_lambda') @docval({'name': 'name', 'type': str, 'doc': 'the name of this electrode'}, # required {'name': 'description', 'type': str, 'doc': 'Any notes or comments about the channel.'}, # required {'name': 'emission_lambda', 'type': float, 'doc': 'Emission wavelength for channel, in nm.'}) # required def __init__(self, **kwargs): description, emission_lambda = popargs("description", "emission_lambda", kwargs) super().__init__(**kwargs) self.description = description self.emission_lambda = emission_lambda @register_class('ImagingPlane', CORE_NAMESPACE) class ImagingPlane(NWBContainer): """An imaging plane and its metadata.""" __nwbfields__ = ({'name': 'optical_channel', 'child': True}, 'description', 'device', 'excitation_lambda', 'imaging_rate', 'indicator', 'location', 'manifold', 'conversion', 'unit', 'reference_frame') @docval(*get_docval(NWBContainer.__init__, 'name'), # required {'name': 'optical_channel', 'type': (list, OpticalChannel), # required 'doc': 'One of possibly many groups storing channel-specific data.'}, {'name': 'description', 'type': str, 'doc': 'Description of this ImagingPlane.'}, # required {'name': 'device', 'type': Device, 'doc': 'the device that was used to record'}, # required {'name': 'excitation_lambda', 'type': float, 'doc': 'Excitation wavelength in nm.'}, # required {'name': 'indicator', 'type': str, 'doc': 'Calcium indicator'}, # required {'name': 'location', 'type': str, 'doc': 'Location of image plane.'}, # required {'name': 'imaging_rate', 'type': float, 'doc': 'Rate images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be ' 'stored there instead.', 'default': None}, {'name': 'manifold', 'type': 'array_data', 'doc': ('DEPRECATED: Physical position of each pixel. size=("height", "width", "xyz"). ' 'Deprecated in favor of origin_coords and grid_spacing.'), 'default': None}, {'name': 'conversion', 'type': float, 'doc': ('DEPRECATED: Multiplier to get from stored values to specified unit (e.g., 1e-3 for millimeters) ' 'Deprecated in favor of origin_coords and grid_spacing.'), 'default': 1.0}, {'name': 'unit', 'type': str, 'doc': 'DEPRECATED: Base unit that coordinates are stored in (e.g., Meters). ' 'Deprecated in favor of origin_coords_unit and grid_spacing_unit.', 'default': 'meters'}, {'name': 'reference_frame', 'type': str, 'doc': 'Describes position and reference frame of manifold based on position of first element ' 'in manifold.', 'default': None}, {'name': 'origin_coords', 'type': 'array_data', 'doc': 'Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for ' '3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma).', 'default': None}, {'name': 'origin_coords_unit', 'type': str, 'doc': "Measurement units for origin_coords. The default value is 'meters'.", 'default': 'meters'}, {'name': 'grid_spacing', 'type': 'array_data', 'doc': "Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes " "imaging plane is a regular grid. See also reference_frame to interpret the grid.", 'default': None}, {'name': 'grid_spacing_unit', 'type': str, 'doc': "Measurement units for grid_spacing. The default value is 'meters'.", 'default': 'meters'}) def __init__(self, **kwargs): keys_to_set = ('optical_channel', 'description', 'device', 'excitation_lambda', 'imaging_rate', 'indicator', 'location', 'manifold', 'conversion', 'unit', 'reference_frame', 'origin_coords', 'origin_coords_unit', 'grid_spacing', 'grid_spacing_unit') args_to_set = popargs_to_dict(keys_to_set, kwargs) super().__init__(**kwargs) if not isinstance(args_to_set['optical_channel'], list): args_to_set['optical_channel'] = [args_to_set['optical_channel']] if args_to_set['manifold'] is not None: warnings.warn("The 'manifold' argument is deprecated in favor of 'origin_coords' and 'grid_spacing'.", DeprecationWarning) if args_to_set['conversion'] != 1.0: warnings.warn("The 'conversion' argument is deprecated in favor of 'origin_coords' and 'grid_spacing'.", DeprecationWarning) if args_to_set['unit'] != 'meters': warnings.warn("The 'unit' argument is deprecated in favor of 'origin_coords_unit' and 'grid_spacing_unit'.", DeprecationWarning) for key, val in args_to_set.items(): setattr(self, key, val) @register_class("OnePhotonSeries", CORE_NAMESPACE) class OnePhotonSeries(ImageSeries): """Image stack recorded over time from 1-photon microscope.""" __nwbfields__ = ( "imaging_plane", "pmt_gain", "scan_line_rate", "exposure_time", "binning", "power", "intensity" ) @docval( *get_docval(ImageSeries.__init__, "name"), # required {"name": "imaging_plane", "type": ImagingPlane, "doc": "Imaging plane class/pointer."}, # required *get_docval(ImageSeries.__init__, "data", "unit", "format"), {"name": "pmt_gain", "type": float, "doc": "Photomultiplier gain.", "default": None}, { "name": "scan_line_rate", "type": float, "doc": ( "Lines imaged per second. This is also stored in /general/optophysiology but is kept " "here as it is useful information for analysis, and so good to be stored w/ the actual data." ), "default": None, }, { "name": "exposure_time", "type": float, "doc": "Exposure time of the sample; often the inverse of the frequency.", "default": None, }, { "name": "binning", "type": (int, "uint"), "doc": "Amount of pixels combined into 'bins'; could be 1, 2, 4, 8, etc.", "default": None, }, { "name": "power", "type": float, "doc": "Power of the excitation in mW, if known.", "default": None, }, { "name": "intensity", "type": float, "doc": "Intensity of the excitation in mW/mm^2, if known.", "default": None, }, *get_docval( ImageSeries.__init__, "external_file", "starting_frame", "bits_per_pixel", "dimension", "resolution", "conversion", "timestamps", "starting_time", "rate", "comments", "description", "control", "control_description", "device", "offset", ) ) def __init__(self, **kwargs): keys_to_set = ( "imaging_plane", "pmt_gain", "scan_line_rate", "exposure_time", "binning", "power", "intensity" ) args_to_set = popargs_to_dict(keys_to_set, kwargs) super().__init__(**kwargs) if args_to_set["binning"] is not None and args_to_set["binning"] < 0: raise ValueError(f"Binning value must be >= 0: {args_to_set['binning']}") if isinstance(args_to_set["binning"], int): args_to_set["binning"] = np.uint(args_to_set["binning"]) for key, val in args_to_set.items(): setattr(self, key, val) @register_class('TwoPhotonSeries', CORE_NAMESPACE) class TwoPhotonSeries(ImageSeries): """Image stack recorded over time from 2-photon microscope.""" __nwbfields__ = ('field_of_view', 'imaging_plane', 'pmt_gain', 'scan_line_rate') @docval(*get_docval(ImageSeries.__init__, 'name'), # required {'name': 'imaging_plane', 'type': ImagingPlane, 'doc': 'Imaging plane class/pointer.'}, # required *get_docval(ImageSeries.__init__, 'data', 'unit', 'format'), {'name': 'field_of_view', 'type': (Iterable, TimeSeries), 'shape': ((2, ), (3, )), 'doc': 'Width, height and depth of image, or imaged area (meters).', 'default': None}, {'name': 'pmt_gain', 'type': float, 'doc': 'Photomultiplier gain.', 'default': None}, {'name': 'scan_line_rate', 'type': float, 'doc': 'Lines imaged per second. This is also stored in /general/optophysiology but is kept ' 'here as it is useful information for analysis, and so good to be stored w/ the actual data.', 'default': None}, *get_docval(ImageSeries.__init__, 'external_file', 'starting_frame', 'bits_per_pixel', 'dimension', 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'device', 'offset')) def __init__(self, **kwargs): keys_to_set = ("field_of_view", "imaging_plane", "pmt_gain", "scan_line_rate") args_to_set = popargs_to_dict(keys_to_set, kwargs) super().__init__(**kwargs) for key, val in args_to_set.items(): setattr(self, key, val) @register_class('CorrectedImageStack', CORE_NAMESPACE) class CorrectedImageStack(NWBDataInterface): """ An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions). """ __nwbfields__ = ({'name': 'corrected', 'child': True, 'required_name': 'corrected'}, {'name': 'xy_translation', 'child': True, 'required_name': 'xy_translation'}, 'original') @docval({'name': 'name', 'type': str, 'doc': 'The name of this CorrectedImageStack container', 'default': 'CorrectedImageStack'}, {'name': 'corrected', 'type': ImageSeries, 'doc': 'Image stack with frames shifted to the common coordinates. This must have the name "corrected".'}, {'name': 'original', 'type': ImageSeries, 'doc': 'Link to image series that is being registered.'}, {'name': 'xy_translation', 'type': TimeSeries, 'doc': 'Stores the x,y delta necessary to align each frame to the common coordinates, ' 'for example, to align each frame to a reference image. This must have the name "xy_translation".'}) def __init__(self, **kwargs): corrected, original, xy_translation = popargs('corrected', 'original', 'xy_translation', kwargs) super().__init__(**kwargs) self.corrected = corrected self.original = original self.xy_translation = xy_translation @register_class('MotionCorrection', CORE_NAMESPACE) class MotionCorrection(MultiContainerInterface): """ A collection of corrected images stacks. """ __clsconf__ = { 'add': 'add_corrected_image_stack', 'get': 'get_corrected_image_stack', 'create': 'create_corrected_image_stack', 'type': CorrectedImageStack, 'attr': 'corrected_image_stacks' } @register_class('PlaneSegmentation', CORE_NAMESPACE) class PlaneSegmentation(DynamicTable): """ Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them. """ __fields__ = ('imaging_plane', {'name': 'reference_images', 'child': True}) __columns__ = ( {'name': 'image_mask', 'description': 'Image masks for each ROI'}, {'name': 'pixel_mask', 'description': 'Pixel masks for each ROI', 'index': True}, {'name': 'voxel_mask', 'description': 'Voxel masks for each ROI', 'index': True} ) @docval({'name': 'description', 'type': str, # required 'doc': 'Description of image plane, recording wavelength, depth, etc.'}, {'name': 'imaging_plane', 'type': ImagingPlane, # required 'doc': 'the ImagingPlane this ROI applies to'}, {'name': 'name', 'type': str, 'doc': 'name of PlaneSegmentation.', 'default': None}, {'name': 'reference_images', 'type': (ImageSeries, list, dict, tuple), 'default': None, 'doc': 'One or more image stacks that the masks apply to (can be oneelement stack).'}, *get_docval(DynamicTable.__init__, 'id', 'columns', 'colnames')) def __init__(self, **kwargs): imaging_plane, reference_images = popargs('imaging_plane', 'reference_images', kwargs) if kwargs['name'] is None: kwargs['name'] = imaging_plane.name super().__init__(**kwargs) self.imaging_plane = imaging_plane if isinstance(reference_images, ImageSeries): reference_images = (reference_images,) self.reference_images = reference_images @docval({'name': 'pixel_mask', 'type': 'array_data', 'default': None, 'doc': 'pixel mask for 2D ROIs: [(x1, y1, weight1), (x2, y2, weight2), ...]', 'shape': (None, 3)}, {'name': 'voxel_mask', 'type': 'array_data', 'default': None, 'doc': 'voxel mask for 3D ROIs: [(x1, y1, z1, weight1), (x2, y2, z2, weight2), ...]', 'shape': (None, 4)}, {'name': 'image_mask', 'type': 'array_data', 'default': None, 'doc': 'image with the same size of image where positive values mark this ROI', 'shape': [[None]*2, [None]*3]}, {'name': 'id', 'type': int, 'doc': 'the ID for the ROI', 'default': None}, allow_extra=True) def add_roi(self, **kwargs): """Add a Region Of Interest (ROI) data to this""" pixel_mask, voxel_mask, image_mask = popargs('pixel_mask', 'voxel_mask', 'image_mask', kwargs) if image_mask is None and pixel_mask is None and voxel_mask is None: raise ValueError("Must provide 'image_mask' and/or 'pixel_mask'") rkwargs = dict(kwargs) if image_mask is not None: rkwargs['image_mask'] = image_mask if pixel_mask is not None: rkwargs['pixel_mask'] = pixel_mask if voxel_mask is not None: rkwargs['voxel_mask'] = voxel_mask return super().add_row(**rkwargs) @staticmethod def pixel_to_image(pixel_mask): """Converts a 2D pixel_mask of a ROI into an image_mask.""" image_matrix = np.zeros(np.shape(pixel_mask)) npmask = np.asarray(pixel_mask) x_coords = npmask[:, 0].astype(np.int32) y_coords = npmask[:, 1].astype(np.int32) weights = npmask[:, -1] image_matrix[y_coords, x_coords] = weights return image_matrix @staticmethod def image_to_pixel(image_mask): """Converts an image_mask of a ROI into a pixel_mask""" pixel_mask = [] it = np.nditer(image_mask, flags=['multi_index']) while not it.finished: weight = it[0][()] if weight > 0: x = it.multi_index[0] y = it.multi_index[1] pixel_mask.append([x, y, weight]) it.iternext() return pixel_mask @docval({'name': 'description', 'type': str, 'doc': 'a brief description of what the region is'}, {'name': 'region', 'type': (slice, list, tuple), 'doc': 'the indices of the table', 'default': slice(None)}, {'name': 'name', 'type': str, 'doc': 'the name of the ROITableRegion', 'default': 'rois'}) def create_roi_table_region(self, **kwargs): return self.create_region(**kwargs) @register_class('ImageSegmentation', CORE_NAMESPACE) class ImageSegmentation(MultiContainerInterface): """ Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them. """ __clsconf__ = { 'attr': 'plane_segmentations', 'type': PlaneSegmentation, 'add': 'add_plane_segmentation', 'get': 'get_plane_segmentation', 'create': 'create_plane_segmentation' } @docval({'name': 'imaging_plane', 'type': ImagingPlane, 'doc': 'the ImagingPlane this ROI applies to'}, {'name': 'description', 'type': str, 'doc': 'Description of image plane, recording wavelength, depth, etc.', 'default': None}, {'name': 'name', 'type': str, 'doc': 'name of PlaneSegmentation.', 'default': None}) def add_segmentation(self, **kwargs): kwargs.setdefault('description', kwargs['imaging_plane'].description) return self.create_plane_segmentation(**kwargs) @register_class('RoiResponseSeries', CORE_NAMESPACE) class RoiResponseSeries(TimeSeries): ''' ROI responses over an imaging plane. Each column in data should correspond to the signal from one ROI. ''' __nwbfields__ = ({'name': 'rois', 'child': True},) @docval(*get_docval(TimeSeries.__init__, 'name'), # required {'name': 'data', 'type': ('array_data', 'data', TimeSeries), # required 'shape': ((None, ), (None, None)), 'doc': ('The data values. May be 1D or 2D. The first dimension must be time. The optional second ' 'dimension represents ROIs')}, *get_docval(TimeSeries.__init__, 'unit'), {'name': 'rois', 'type': DynamicTableRegion, # required 'doc': 'a table region corresponding to the ROIs that were used to generate this data'}, *get_docval(TimeSeries.__init__, 'resolution', 'conversion', 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', 'offset')) def __init__(self, **kwargs): rois = popargs('rois', kwargs) data_shape = get_data_shape(data=kwargs["data"], strict_no_data_load=True) rois_shape = get_data_shape(data=rois.data, strict_no_data_load=True) if ( data_shape is not None and rois_shape is not None # check that data is 2d and rois is 1d and len(data_shape) == 2 and len(rois_shape) == 1 # check that key dimensions are known and data_shape[1] is not None and rois_shape[0] is not None and data_shape[1] != rois_shape[0] ): if data_shape[0] == rois_shape[0]: warnings.warn("%s '%s': The second dimension of data does not match the length of rois, " "but instead the first does. Data is oriented incorrectly and should be transposed." % (self.__class__.__name__, kwargs["name"])) else: warnings.warn("%s '%s': The second dimension of data does not match the length of rois. " "Your data may be transposed." % (self.__class__.__name__, kwargs["name"])) super().__init__(**kwargs) self.rois = rois @register_class('DfOverF', CORE_NAMESPACE) class DfOverF(MultiContainerInterface): """ dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (ie, same names for ROIs and for image planes). """ __clsconf__ = { 'attr': 'roi_response_series', 'type': RoiResponseSeries, 'add': 'add_roi_response_series', 'get': 'get_roi_response_series', 'create': 'create_roi_response_series' } @register_class('Fluorescence', CORE_NAMESPACE) class Fluorescence(MultiContainerInterface): """ Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes). """ __clsconf__ = { 'attr': 'roi_response_series', 'type': RoiResponseSeries, 'add': 'add_roi_response_series', 'get': 'get_roi_response_series', 'create': 'create_roi_response_series' } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/resources.py0000644000175100001730000000064314467767506016621 0ustar00runnerdockerfrom hdmf.common import HERD as hdmf_HERD from . import get_type_map as tm from hdmf.utils import docval, get_docval class HERD(hdmf_HERD): """ HDMF External Resources Data Structure. A table for mapping user terms (i.e. keys) to resource entities. """ @docval(*get_docval(hdmf_HERD.__init__)) def __init__(self, **kwargs): kwargs['type_map'] = tm() super().__init__(**kwargs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/retinotopy.py0000644000175100001730000001661714467767506017033 0ustar00runnerdockerimport warnings from collections.abc import Iterable from hdmf.utils import docval, popargs, get_docval from . import register_class, CORE_NAMESPACE from .core import NWBDataInterface, NWBData class RetinotopyImage(NWBData): """Gray-scale anatomical image of cortical surface. Array structure: [rows][columns] """ __nwbfields__ = ('bits_per_pixel', 'dimension', 'format', 'field_of_view') @docval({'name': 'name', 'type': str, 'doc': 'Name of this retinotopy image'}, {'name': 'data', 'type': Iterable, 'doc': 'Data field.'}, {'name': 'bits_per_pixel', 'type': int, 'doc': 'Number of bits used to represent each value. This is necessary to determine maximum ' '(white) pixel value.'}, {'name': 'dimension', 'type': Iterable, 'shape': (2, ), 'doc': 'Number of rows and columns in the image.'}, {'name': 'format', 'type': Iterable, 'doc': 'Format of image. Right now only "raw" supported.'}, {'name': 'field_of_view', 'type': Iterable, 'shape': (2, ), 'doc': 'Size of viewing area, in meters.'}) def __init__(self, **kwargs): bits_per_pixel, dimension, format, field_of_view = popargs( 'bits_per_pixel', 'dimension', 'format', 'field_of_view', kwargs) super().__init__(**kwargs) self.bits_per_pixel = bits_per_pixel self.dimension = dimension self.format = format self.field_of_view = field_of_view class FocalDepthImage(RetinotopyImage): """Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns]. """ __nwbfields__ = ('focal_depth', ) @docval(*get_docval(RetinotopyImage.__init__), {'name': 'focal_depth', 'type': float, 'doc': 'Focal depth offset, in meters.'}) def __init__(self, **kwargs): focal_depth = popargs('focal_depth', kwargs) super().__init__(**kwargs) self.focal_depth = focal_depth class RetinotopyMap(NWBData): """Abstract two-dimensional map of responses to stimuli along a single response axis (e.g., altitude) """ __nwbfields__ = ('field_of_view', 'dimension') @docval({'name': 'name', 'type': str, 'doc': 'the name of this axis map'}, {'name': 'data', 'type': Iterable, 'shape': (None, None), 'doc': 'data field.'}, {'name': 'field_of_view', 'type': Iterable, 'shape': (2, ), 'doc': 'Size of viewing area, in meters.'}, {'name': 'dimension', 'type': Iterable, 'shape': (2, ), 'doc': 'Number of rows and columns in the image'}) def __init__(self, **kwargs): field_of_view, dimension = popargs('field_of_view', 'dimension', kwargs) super().__init__(**kwargs) self.field_of_view = field_of_view self.dimension = dimension class AxisMap(RetinotopyMap): """Abstract two-dimensional map of responses to stimuli along a single response axis (e.g., altitude) with unit """ __nwbfields__ = ('unit', ) @docval(*get_docval(RetinotopyMap.__init__, 'name', 'data', 'field_of_view'), {'name': 'unit', 'type': str, 'doc': 'Unit that axis data is stored in (e.g., degrees)'}, *get_docval(RetinotopyMap.__init__, 'dimension')) def __init__(self, **kwargs): unit = popargs('unit', kwargs) super().__init__(**kwargs) self.unit = unit @register_class('ImagingRetinotopy', CORE_NAMESPACE) class ImagingRetinotopy(NWBDataInterface): """ Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. This group does not store the raw responses imaged during retinotopic mapping or the stimuli presented, but rather the resulting phase and power maps after applying a Fourier transform on the averaged responses. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x). """ __nwbfields__ = ({'name': 'sign_map', 'child': True}, {'name': 'axis_1_phase_map', 'child': True}, {'name': 'axis_1_power_map', 'child': True}, {'name': 'axis_2_phase_map', 'child': True}, {'name': 'axis_2_power_map', 'child': True}, {'name': 'focal_depth_image', 'child': True}, {'name': 'vasculature_image', 'child': True}, 'axis_descriptions') @docval({'name': 'sign_map', 'type': RetinotopyMap, 'doc': 'Sine of the angle between the direction of the gradient in axis_1 and axis_2.'}, {'name': 'axis_1_phase_map', 'type': AxisMap, 'doc': 'Phase response to stimulus on the first measured axis.'}, {'name': 'axis_1_power_map', 'type': AxisMap, 'doc': 'Power response on the first measured axis. Response is scaled so 0.0 is no power in ' 'the response and 1.0 is maximum relative power.'}, {'name': 'axis_2_phase_map', 'type': AxisMap, 'doc': 'Phase response to stimulus on the second measured axis.'}, {'name': 'axis_2_power_map', 'type': AxisMap, 'doc': 'Power response on the second measured axis. Response is scaled so 0.0 is no ' 'power in the response and 1.0 is maximum relative power.'}, {'name': 'axis_descriptions', 'type': Iterable, 'shape': (2, ), 'doc': 'Two-element array describing the contents of the two response axis fields. ' 'Description should be something like ["altitude", "azimuth"] or ["radius", "theta"].'}, {'name': 'focal_depth_image', 'type': FocalDepthImage, 'doc': 'Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) ' 'as data collection. Array format: [rows][columns].'}, {'name': 'vasculature_image', 'type': RetinotopyImage, 'doc': 'Gray-scale anatomical image of cortical surface. Array structure: [rows][columns].'}, {'name': 'name', 'type': str, 'doc': 'the name of this container', 'default': 'ImagingRetinotopy'}) def __init__(self, **kwargs): axis_1_phase_map, axis_1_power_map, axis_2_phase_map, axis_2_power_map, axis_descriptions, \ focal_depth_image, sign_map, vasculature_image = popargs( 'axis_1_phase_map', 'axis_1_power_map', 'axis_2_phase_map', 'axis_2_power_map', 'axis_descriptions', 'focal_depth_image', 'sign_map', 'vasculature_image', kwargs) super().__init__(**kwargs) warnings.warn("The ImagingRetinotopy class currently cannot be written to or read from a file. " "This is a known bug and will be fixed in a future release of PyNWB.") self.axis_1_phase_map = axis_1_phase_map self.axis_1_power_map = axis_1_power_map self.axis_2_phase_map = axis_2_phase_map self.axis_2_power_map = axis_2_power_map self.axis_descriptions = axis_descriptions self.focal_depth_image = focal_depth_image self.sign_map = sign_map self.vasculature_image = vasculature_image ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/spec.py0000644000175100001730000001611514467767506015542 0ustar00runnerdockerfrom copy import copy, deepcopy from hdmf.spec import (LinkSpec, GroupSpec, DatasetSpec, SpecNamespace, NamespaceBuilder, AttributeSpec, DtypeSpec, RefSpec) from hdmf.spec.write import export_spec # noqa: F401 from hdmf.utils import docval, get_docval from . import CORE_NAMESPACE def __swap_inc_def(cls): args = get_docval(cls.__init__) clsname = 'NWB%s' % cls.__name__ ret = list() # do not set default neurodata_type_inc for base hdmf-common types that should not have data_type_inc for arg in args: if arg['name'] == 'data_type_def': ret.append({'name': 'neurodata_type_def', 'type': str, 'doc': 'the NWB data type this spec defines', 'default': None}) elif arg['name'] == 'data_type_inc': ret.append({'name': 'neurodata_type_inc', 'type': (clsname, str), 'doc': 'the NWB data type this spec includes', 'default': None}) else: ret.append(copy(arg)) return ret _ref_docval = __swap_inc_def(RefSpec) class NWBRefSpec(RefSpec): @docval(*deepcopy(_ref_docval)) def __init__(self, **kwargs): super().__init__(**kwargs) _attr_docval = __swap_inc_def(AttributeSpec) class NWBAttributeSpec(AttributeSpec): @docval(*deepcopy(_attr_docval)) def __init__(self, **kwargs): super().__init__(**kwargs) _link_docval = __swap_inc_def(LinkSpec) class NWBLinkSpec(LinkSpec): @docval(*deepcopy(_link_docval)) def __init__(self, **kwargs): super().__init__(**kwargs) @property def neurodata_type_inc(self): ''' The neurodata type of target specification ''' return self.data_type_inc class BaseStorageOverride: ''' This class is used for the purpose of overriding BaseStorageSpec classmethods, without creating diamond inheritance hierarchies. ''' __type_key = 'neurodata_type' __inc_key = 'neurodata_type_inc' __def_key = 'neurodata_type_def' @classmethod def type_key(cls): ''' Get the key used to store data type on an instance''' return cls.__type_key @classmethod def inc_key(cls): ''' Get the key used to define a data_type include.''' return cls.__inc_key @classmethod def def_key(cls): ''' Get the key used to define a data_type definition.''' return cls.__def_key @property def neurodata_type_inc(self): return self.data_type_inc @property def neurodata_type_def(self): return self.data_type_def @classmethod def build_const_args(cls, spec_dict): """Extend base functionality to remap data_type_def and data_type_inc keys""" spec_dict = copy(spec_dict) proxy = super() if proxy.inc_key() in spec_dict: spec_dict[cls.inc_key()] = spec_dict.pop(proxy.inc_key()) if proxy.def_key() in spec_dict: spec_dict[cls.def_key()] = spec_dict.pop(proxy.def_key()) ret = proxy.build_const_args(spec_dict) return ret @classmethod def _translate_kwargs(cls, kwargs): """Swap neurodata_type_def and neurodata_type_inc for data_type_def and data_type_inc, respectively""" proxy = super() kwargs[proxy.def_key()] = kwargs.pop(cls.def_key()) kwargs[proxy.inc_key()] = kwargs.pop(cls.inc_key()) return kwargs _dtype_docval = __swap_inc_def(DtypeSpec) class NWBDtypeSpec(DtypeSpec): @docval(*deepcopy(_dtype_docval)) def __init__(self, **kwargs): super().__init__(**kwargs) _dataset_docval = __swap_inc_def(DatasetSpec) class NWBDatasetSpec(BaseStorageOverride, DatasetSpec): ''' The Spec class to use for NWB dataset specifications. Classes will automatically include NWBData if None is specified. ''' @docval(*deepcopy(_dataset_docval)) def __init__(self, **kwargs): kwargs = self._translate_kwargs(kwargs) # set data_type_inc to NWBData only if it is not specified and the type is not an HDMF base type if kwargs['data_type_inc'] is None and kwargs['data_type_def'] not in (None, 'Data'): kwargs['data_type_inc'] = 'NWBData' super().__init__(**kwargs) _group_docval = __swap_inc_def(GroupSpec) class NWBGroupSpec(BaseStorageOverride, GroupSpec): ''' The Spec class to use for NWB group specifications. Classes will automatically include NWBContainer if None is specified. ''' @docval(*deepcopy(_group_docval)) def __init__(self, **kwargs): kwargs = self._translate_kwargs(kwargs) # set data_type_inc to NWBData only if it is not specified and the type is not an HDMF base type # NOTE: CSRMatrix in hdmf-common-schema does not have a data_type_inc but should not inherit from # NWBContainer. This will be fixed in hdmf-common-schema 1.2.1. if kwargs['data_type_inc'] is None and kwargs['data_type_def'] not in (None, 'Container', 'CSRMatrix'): kwargs['data_type_inc'] = 'NWBContainer' super().__init__(**kwargs) @classmethod def dataset_spec_cls(cls): return NWBDatasetSpec @docval({'name': 'neurodata_type', 'type': str, 'doc': 'the neurodata_type to retrieve'}) def get_neurodata_type(self, **kwargs): ''' Get a specification by "neurodata_type" ''' return super().get_data_type(kwargs['neurodata_type']) @docval(*deepcopy(_group_docval)) def add_group(self, **kwargs): ''' Add a new specification for a subgroup to this group specification ''' doc = kwargs.pop('doc') spec = NWBGroupSpec(doc, **kwargs) self.set_group(spec) return spec @docval(*deepcopy(_dataset_docval)) def add_dataset(self, **kwargs): ''' Add a new specification for a subgroup to this group specification ''' doc = kwargs.pop('doc') spec = NWBDatasetSpec(doc, **kwargs) self.set_dataset(spec) return spec class NWBNamespace(SpecNamespace): ''' A Namespace class for NWB ''' __types_key = 'neurodata_types' @classmethod def types_key(cls): return cls.__types_key class NWBNamespaceBuilder(NamespaceBuilder): ''' A class for writing namespace and spec files for extensions of types in the NWB core namespace ''' @docval({'name': 'doc', 'type': str, 'doc': 'a description about what this namespace represents'}, {'name': 'name', 'type': str, 'doc': 'the name of this namespace'}, {'name': 'full_name', 'type': str, 'doc': 'extended full name of this namespace', 'default': None}, {'name': 'version', 'type': (str, tuple, list), 'doc': 'Version number of the namespace', 'default': None}, {'name': 'author', 'type': (str, list), 'doc': 'Author or list of authors.', 'default': None}, {'name': 'contact', 'type': (str, list), 'doc': 'List of emails. Ordering should be the same as for author', 'default': None}) def __init__(self, **kwargs): ''' Create a NWBNamespaceBuilder ''' kwargs['namespace_cls'] = NWBNamespace super().__init__(**kwargs) self.include_namespace(CORE_NAMESPACE) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5460274 pynwb-2.5.0/src/pynwb/testing/0000755000175100001730000000000014467767767015720 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/__init__.py0000644000175100001730000000043114467767506020016 0ustar00runnerdockerfrom hdmf.testing import TestCase, H5RoundTripMixin from .testh5io import NWBH5IOMixin, AcquisitionH5IOMixin, NWBH5IOFlexMixin from .utils import remove_test_file from .icephys_testutils import create_icephys_stimulus_and_response, create_icephys_testfile CORE_NAMESPACE = 'core' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/icephys_testutils.py0000644000175100001730000002171014467767506022046 0ustar00runnerdocker""" Module with helper functions to facilitate testing """ import numpy as np from datetime import datetime from dateutil.tz import tzlocal from pynwb.file import NWBFile from pynwb.icephys import (VoltageClampStimulusSeries, VoltageClampSeries) from pynwb import NWBHDF5IO def create_icephys_stimulus_and_response(sweep_number, electrode, randomize_data): """ Internal helper function to construct a dummy stimulus and response pair representing an intracellular recording: :param sweep_number: Integer sweep number of the recording :type sweep_number: int :param electrode: Intracellular electrode used :type electrode: pynwb.icephys.IntracellularElectrode :param randomize_data: Randomize data values in the stimulus and response :type randomize_data: bool :returns: Tuple of VoltageClampStimulusSeries with the stimulus and VoltageClampSeries with the response. """ stimulus = VoltageClampStimulusSeries( name="ccss_"+str(sweep_number), data=[1, 2, 3, 4, 5] if not randomize_data else np.random.rand(10), starting_time=123.6 if not randomize_data else (np.random.rand() * 100), rate=10e3 if not randomize_data else int(np.random.rand()*10) * 1000 + 1000., electrode=electrode, gain=0.1 if not randomize_data else np.random.rand(), sweep_number=sweep_number) # Create and ic-response response = VoltageClampSeries( name='vcs_'+str(sweep_number), data=[0.1, 0.2, 0.3, 0.4, 0.5] if not randomize_data else np.random.rand(10), conversion=1e-12, resolution=np.nan, starting_time=123.6 if not randomize_data else (np.random.rand() * 100), rate=20e3 if not randomize_data else int(np.random.rand() * 20) * 1000. + 1000., electrode=electrode, gain=0.02 if not randomize_data else np.random.rand(), capacitance_slow=100e-12, resistance_comp_correction=70.0 if not randomize_data else 70.0 + np.random.rand(), sweep_number=sweep_number) return stimulus, response def create_icephys_testfile(filename=None, add_custom_columns=True, randomize_data=True, with_missing_stimulus=True): """ Create a small but relatively complex icephys test file that we can use for testing of queries. :param filename: The name of the output file to be generated. If set to None then the file is not written but only created in memory :type filename: str, None :param add_custom_colums: Add custom metadata columns to each table :type add_custom_colums: bool :param randomize_data: Randomize data values in the stimulus and response :type randomize_data: bool :returns: ICEphysFile NWBFile object created for writing. NOTE: If filename is provided then the file is written to disk, but the function does not read the file back. If you want to use the file from disk then you will need to read it with NWBHDF5IO. :rtype: ICEphysFile """ nwbfile = NWBFile( session_description='my first synthetic recording', identifier='EXAMPLE_ID', session_start_time=datetime.now(tzlocal()), experimenter='Dr. Bilbo Baggins', lab='Bag End Laboratory', institution='University of Middle Earth at the Shire', experiment_description='I went on an adventure with thirteen dwarves to reclaim vast treasures.', session_id='LONELYMTN') # Add a device device = nwbfile.create_device(name='Heka ITC-1600') # Add an intracellular electrode electrode0 = nwbfile.create_icephys_electrode( name="elec0", description='a mock intracellular electrode', device=device) # Add an intracellular electrode electrode1 = nwbfile.create_icephys_electrode( name="elec1", description='another mock intracellular electrode', device=device) # Add the intracelluar recordings for sweep_number in range(20): elec = (electrode0 if (sweep_number % 2 == 0) else electrode1) stim, resp = create_icephys_stimulus_and_response(sweep_number=np.uint64(sweep_number), electrode=elec, randomize_data=randomize_data) if with_missing_stimulus and sweep_number in [0, 10]: stim = None nwbfile.add_intracellular_recording(electrode=elec, stimulus=stim, response=resp, id=sweep_number) nwbfile.intracellular_recordings.add_column(name='recording_tags', data=['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'C3', 'D1', 'D2', 'D3', 'A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'C3', 'D1', 'D2', 'D3'], description='String with a set of recording tags') # Add simultaneous_recordings nwbfile.add_icephys_simultaneous_recording(recordings=[0, 1], id=np.int64(100)) nwbfile.add_icephys_simultaneous_recording(recordings=[2, 3], id=np.int64(101)) nwbfile.add_icephys_simultaneous_recording(recordings=[4, 5, 6], id=np.int64(102)) nwbfile.add_icephys_simultaneous_recording(recordings=[7, 8, 9], id=np.int64(103)) nwbfile.add_icephys_simultaneous_recording(recordings=[10, 11], id=np.int64(104)) nwbfile.add_icephys_simultaneous_recording(recordings=[12, 13], id=np.int64(105)) nwbfile.add_icephys_simultaneous_recording(recordings=[14, 15, 16], id=np.int64(106)) nwbfile.add_icephys_simultaneous_recording(recordings=[17, 18, 19], id=np.int64(107)) if add_custom_columns: nwbfile.icephys_simultaneous_recordings.add_column( name='tag', data=np.arange(8), description='some integer tag for a sweep') # Add sequential recordings nwbfile.add_icephys_sequential_recording(simultaneous_recordings=[0, 1], id=np.int64(1000), stimulus_type="StimType_1") nwbfile.add_icephys_sequential_recording(simultaneous_recordings=[2, ], id=np.int64(1001), stimulus_type="StimType_2") nwbfile.add_icephys_sequential_recording(simultaneous_recordings=[3, ], id=np.int64(1002), stimulus_type="StimType_3") nwbfile.add_icephys_sequential_recording(simultaneous_recordings=[4, 5], id=np.int64(1003), stimulus_type="StimType_1") nwbfile.add_icephys_sequential_recording(simultaneous_recordings=[6, ], id=np.int64(1004), stimulus_type="StimType_2") nwbfile.add_icephys_sequential_recording(simultaneous_recordings=[7, ], id=np.int64(1005), stimulus_type="StimType_3") if add_custom_columns: nwbfile.icephys_sequential_recordings.add_column( name='type', data=['T1', 'T2', 'T3', 'T1', 'T2', 'T3'], description='type of the sequential recording') # Add repetitions nwbfile.add_icephys_repetition(sequential_recordings=[0, ], id=np.int64(10000)) nwbfile.add_icephys_repetition(sequential_recordings=[1, 2], id=np.int64(10001)) nwbfile.add_icephys_repetition(sequential_recordings=[3, ], id=np.int64(10002)) nwbfile.add_icephys_repetition(sequential_recordings=[4, 5], id=np.int64(10003)) if add_custom_columns: nwbfile.icephys_repetitions.add_column( name='type', data=['R1', 'R2', 'R1', 'R2'], description='some repetition type indicator') # Add experimental_conditions nwbfile.add_icephys_experimental_condition(repetitions=[0, 1], id=np.int64(100000)) nwbfile.add_icephys_experimental_condition(repetitions=[2, 3], id=np.int64(100001)) if add_custom_columns: nwbfile.icephys_experimental_conditions.add_column( name='temperature', data=[32., 24.], description='Temperatur in C') # Write our test file if filename is not None: with NWBHDF5IO(filename, 'w') as io: io.write(nwbfile) # Return our in-memory NWBFile return nwbfile ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/make_test_files.py0000644000175100001730000001667314467767506021434 0ustar00runnerdockerfrom datetime import datetime import numpy as np from pathlib import Path from pynwb import NWBFile, NWBHDF5IO, __version__, TimeSeries, get_class, load_namespaces from pynwb.file import Subject from pynwb.image import ImageSeries from pynwb.spec import NWBNamespaceBuilder, export_spec, NWBGroupSpec, NWBAttributeSpec # pynwb 1.0.2 should be installed with hdmf 1.0.3 # pynwb 1.0.3 should be installed with hdmf 1.0.5 # pynwb 1.1.0 should be installed with hdmf 1.2.0 # pynwb 1.1.1+ should be installed with an appropriate version of hdmf def _write(test_name, nwbfile): filename = str("%s/%s_%s.nwb") % (Path(__file__).parent, __version__, test_name) with NWBHDF5IO(filename, 'w') as io: io.write(nwbfile) return filename def _make_empty(): nwbfile = NWBFile(session_description='ADDME', identifier='ADDME', session_start_time=datetime.now().astimezone()) test_name = 'nwbfile' _write(test_name, nwbfile) def _make_str_experimenter(): nwbfile = NWBFile(session_description='ADDME', identifier='ADDME', session_start_time=datetime.now().astimezone(), experimenter='one experimenter') test_name = 'str_experimenter' _write(test_name, nwbfile) def _make_str_pub(): nwbfile = NWBFile(session_description='ADDME', identifier='ADDME', session_start_time=datetime.now().astimezone(), related_publications='one publication') test_name = 'str_pub' _write(test_name, nwbfile) def _make_timeseries_no_data(): nwbfile = NWBFile(session_description='ADDME', identifier='ADDME', session_start_time=datetime.now().astimezone()) ts = TimeSeries( name='test_timeseries', rate=1., unit='unit', ) nwbfile.add_acquisition(ts) test_name = 'timeseries_no_data' _write(test_name, nwbfile) def _make_timeseries_no_unit(): nwbfile = NWBFile(session_description='ADDME', identifier='ADDME', session_start_time=datetime.now().astimezone()) ts = TimeSeries( name='test_timeseries', data=[0], rate=1., ) nwbfile.add_acquisition(ts) test_name = 'timeseries_no_unit' _write(test_name, nwbfile) def _make_imageseries_no_data(): """Create a test file with an ImageSeries with no data.""" nwbfile = NWBFile(session_description='ADDME', identifier='ADDME', session_start_time=datetime.now().astimezone()) image_series = ImageSeries( name='test_imageseries', external_file=['external_file'], starting_frame=[1], format='external', timestamps=[1., 2., 3.] ) nwbfile.add_acquisition(image_series) test_name = 'imageseries_no_data' _write(test_name, nwbfile) def _make_imageseries_no_unit(): """Create a test file with an ImageSeries with data and no unit.""" nwbfile = NWBFile(session_description='ADDME', identifier='ADDME', session_start_time=datetime.now().astimezone()) image_series = ImageSeries( name='test_imageseries', data=np.ones((3, 3, 3)), timestamps=[1., 2., 3.] ) nwbfile.add_acquisition(image_series) test_name = 'imageseries_no_unit' _write(test_name, nwbfile) def _make_imageseries_non_external_format(): """Create a test file with an ImageSeries with external_file set and format != 'external'.""" nwbfile = NWBFile(session_description='ADDME', identifier='ADDME', session_start_time=datetime.now().astimezone()) image_series = ImageSeries( name='test_imageseries', external_file=['external_file'], starting_frame=[1], format='tiff', timestamps=[1., 2., 3.] ) nwbfile.add_acquisition(image_series) test_name = 'imageseries_non_external_format' _write(test_name, nwbfile) def _make_imageseries_nonmatch_starting_frame(): """Create a test file with an ImageSeries where len(starting_frame) != len(external_file).""" nwbfile = NWBFile(session_description='ADDME', identifier='ADDME', session_start_time=datetime.now().astimezone()) image_series = ImageSeries( name='test_imageseries', external_file=['external_file'], starting_frame=[1, 2, 3], format='external', timestamps=[1., 2., 3.] ) nwbfile.add_acquisition(image_series) test_name = 'imageseries_nonmatch_starting_frame' _write(test_name, nwbfile) def _make_empty_with_extension(): ns_builder = NWBNamespaceBuilder( doc="An NWB test extension", name="ndx-testextension", version="0.1.0", author="PyNWB Test File Generator", contact="my_email@example.com", ) ns_builder.include_type('TimeSeries', namespace='core') tetrode_series = NWBGroupSpec( neurodata_type_def='TimeSeriesWithID', neurodata_type_inc='TimeSeries', doc=('An extension of TimeSeries to include an ID.'), attributes=[ NWBAttributeSpec( name='id', doc='The time series ID.', dtype='int32' ), ], ) new_data_types = [tetrode_series] # export the spec to yaml files in the current directory export_spec(ns_builder, new_data_types, output_dir=".") nwbfile = NWBFile(session_description='ADDME', identifier='ADDME', session_start_time=datetime.now().astimezone()) load_namespaces("ndx-testextension.namespace.yaml") # load from the current directory TimeSeriesWithID = get_class("TimeSeriesWithID", "ndx-testextension") ts = TimeSeriesWithID( name="test_ts", data=[1., 2., 3.], description="ADDME", unit="ADDME", rate=1., id=1, ) nwbfile.add_acquisition(ts) test_name = 'nwbfile_with_extension' _write(test_name, nwbfile) def _make_subject_without_age_reference(): """Create a test file without a value for age_reference.""" nwbfile = NWBFile(session_description='ADDME', identifier='ADDME', session_start_time=datetime.now().astimezone()) subject = Subject( age="P90D", description="A rat", subject_id="RAT123", ) nwbfile.subject = subject test_name = 'subject_no_age__reference' _write(test_name, nwbfile) if __name__ == '__main__': # install these versions of PyNWB and run this script to generate new files # python src/pynwb/testing/make_test_files.py # files will be made in src/pynwb/testing/ # files should be moved to tests/back_compat/ # NOTE: this script is run in the GitHub Actions workflow generate_test_files.yml if __version__ == '1.1.2': _make_empty() _make_str_experimenter() _make_str_pub() if __version__ == '1.5.1': _make_timeseries_no_data() _make_timeseries_no_unit() _make_imageseries_no_data() _make_imageseries_no_unit() if __version__ == '2.1.0': _make_imageseries_no_data() _make_imageseries_non_external_format() _make_imageseries_nonmatch_starting_frame() _make_empty_with_extension() if __version__ == "2.2.0": _make_subject_without_age_reference() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5500274 pynwb-2.5.0/src/pynwb/testing/mock/0000755000175100001730000000000014467767767016651 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/mock/__init__.py0000644000175100001730000000112214467767506020745 0ustar00runnerdocker""" The mock module provides mock instances of common neurodata types which can be used to write tests for downstream libraries. For instance, to write an RoiResponseSeries, you need a PlaneSegmentation, which requires an ImagingPlane, which in turn requires an OpticalChannel and a Device, all of which need to be populated with reasonable mock data. This library streamlines the process of creating mock objects by generating the required prerequisites for this object on-the-fly and automatically using reasonable defaults. Any of these default objects and parameters can be overridden. """ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/mock/base.py0000644000175100001730000000227614467767506020133 0ustar00runnerdockerfrom typing import Optional import numpy as np from ... import NWBFile from ...base import TimeSeries from .utils import name_generator def mock_TimeSeries( name: Optional[str] = None, data=None, unit: str = "volts", resolution: float = -1.0, conversion: float = 1.0, timestamps=None, starting_time: Optional[float] = None, rate: Optional[float] = 10.0, comments: str = "no comments", description: str = "no description", control=None, control_description=None, continuity=None, nwbfile: Optional[NWBFile] = None, offset=0., ) -> TimeSeries: time_series = TimeSeries( name=name or name_generator("TimeSeries"), data=data if data is not None else np.array([1, 2, 3, 4]), unit=unit, resolution=resolution, conversion=conversion, timestamps=timestamps, starting_time=starting_time, rate=rate, comments=comments, description=description, control=control, control_description=control_description, continuity=continuity, offset=offset, ) if nwbfile is not None: nwbfile.add_acquisition(time_series) return time_series ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/mock/behavior.py0000644000175100001730000000511114467767506021007 0ustar00runnerdockerfrom typing import Optional import numpy as np from ... import NWBFile, TimeSeries from ...behavior import ( PupilTracking, Position, SpatialSeries, CompassDirection, ) from .utils import name_generator from .base import mock_TimeSeries def mock_SpatialSeries( name: Optional[str] = None, data=None, reference_frame: str = "lower left is (0, 0)", unit: str = "meters", conversion=1.0, resolution=-1.0, timestamps=None, starting_time: Optional[float] = None, rate: Optional[float] = 10.0, comments: str = "no comments", description: str = "no description", control=None, control_description=None, nwbfile: Optional[NWBFile] = None, ) -> SpatialSeries: spatial_series = SpatialSeries( name=name or name_generator("SpatialSeries"), data=data if data is not None else np.array([1, 2, 3, 4]), reference_frame=reference_frame, unit=unit, conversion=conversion, resolution=resolution, timestamps=timestamps, starting_time=starting_time, rate=rate, comments=comments, description=description, control=control, control_description=control_description, ) if nwbfile is not None: nwbfile.add_acquisition(spatial_series) return spatial_series def mock_Position( name: Optional[str] = None, spatial_series: Optional[SpatialSeries] = None, nwbfile: Optional[NWBFile] = None, ) -> Position: position = Position( name=name or name_generator("Position"), spatial_series=spatial_series or [mock_SpatialSeries(nwbfile=nwbfile)] ) if nwbfile is not None: nwbfile.add_acquisition(position) return position def mock_PupilTracking( name: Optional[str] = None, time_series: Optional[TimeSeries] = None, nwbfile: Optional[NWBFile] = None ) -> PupilTracking: pupil_tracking = PupilTracking( name=name or name_generator("PupilTracking"), time_series=time_series or [mock_TimeSeries(nwbfile=nwbfile)] ) if nwbfile is not None: nwbfile.add_acquisition(pupil_tracking) return pupil_tracking def mock_CompassDirection( name: Optional[str] = None, spatial_series: Optional[SpatialSeries] = None, nwbfile: Optional[NWBFile] = None ) -> CompassDirection: compass_direction = CompassDirection( name=name or name_generator("CompassDirection"), spatial_series=spatial_series or [mock_SpatialSeries(unit="radians", nwbfile=nwbfile)], ) if nwbfile is not None: nwbfile.add_acquisition(compass_direction) return compass_direction ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/mock/device.py0000644000175100001730000000101314467767506020444 0ustar00runnerdockerfrom typing import Optional from ... import NWBFile from ...device import Device from .utils import name_generator def mock_Device( name: Optional[str] = None, description: str = "description", manufacturer: Optional[str] = None, nwbfile: Optional[NWBFile] = None, ) -> Device: device = Device( name=name or name_generator("Device"), description=description, manufacturer=manufacturer, ) if nwbfile is not None: nwbfile.add_device(device) return device ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/mock/ecephys.py0000644000175100001730000000651414467767506020660 0ustar00runnerdockerfrom typing import Optional import numpy as np from hdmf.common.table import DynamicTableRegion, DynamicTable from ...device import Device from ...file import ElectrodeTable, NWBFile from ...ecephys import ElectricalSeries, ElectrodeGroup, SpikeEventSeries from .device import mock_Device from .utils import name_generator def mock_ElectrodeGroup( name: Optional[str] = None, description: str = "description", location: str = "location", device: Optional[Device] = None, position: Optional[str] = None, nwbfile: Optional[NWBFile] = None, ) -> ElectrodeGroup: electrode_group = ElectrodeGroup( name=name or name_generator("ElectrodeGroup"), description=description, location=location, device=device or mock_Device(nwbfile=nwbfile), position=position, ) if nwbfile is not None: nwbfile.add_electrode_group(electrode_group) return electrode_group def mock_ElectrodeTable( n_rows: int = 5, group: Optional[ElectrodeGroup] = None, nwbfile: Optional[NWBFile] = None ) -> DynamicTable: electrodes_table = ElectrodeTable() group = group if group is not None else mock_ElectrodeGroup(nwbfile=nwbfile) for i in range(n_rows): electrodes_table.add_row( location="CA1", group=group, group_name=group.name, ) if nwbfile is not None: nwbfile.electrodes = electrodes_table return electrodes_table def mock_electrodes( n_electrodes: int = 5, table: Optional[DynamicTable] = None, nwbfile: Optional[NWBFile] = None ) -> DynamicTableRegion: table = table or mock_ElectrodeTable(n_rows=5, nwbfile=nwbfile) return DynamicTableRegion( name="electrodes", data=list(range(n_electrodes)), description="the first and third electrodes", table=table, ) def mock_ElectricalSeries( name: Optional[str] = None, description: str = "description", data=None, rate: float = 30000.0, timestamps=None, electrodes: Optional[DynamicTableRegion] = None, filtering: str = "filtering", nwbfile: Optional[NWBFile] = None ) -> ElectricalSeries: electrical_series = ElectricalSeries( name=name or name_generator("ElectricalSeries"), description=description, data=data if data is not None else np.ones((10, 5)), rate=rate, timestamps=timestamps, electrodes=electrodes or mock_electrodes(nwbfile=nwbfile), filtering=filtering, ) if nwbfile is not None: nwbfile.add_acquisition(electrical_series) return electrical_series def mock_SpikeEventSeries( name: Optional[str] = None, description: str = "description", data=None, timestamps=np.arange(10).astype(float), electrodes: Optional[DynamicTableRegion] = None, nwbfile: Optional[NWBFile] = None, ) -> SpikeEventSeries: spike_event_series = SpikeEventSeries( name=name or name_generator("SpikeEventSeries"), description=description, data=data if data is not None else np.ones((10, 5)), timestamps=timestamps if timestamps is not None else np.arange(10).astype(float), electrodes=electrodes if electrodes is not None else mock_electrodes(nwbfile=nwbfile), ) if nwbfile is not None: nwbfile.add_acquisition(spike_event_series) return spike_event_series ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/mock/file.py0000644000175100001730000000200114467767506020122 0ustar00runnerdockerfrom typing import Optional from uuid import uuid4 from datetime import datetime from dateutil.tz import tzlocal from ...file import NWBFile, Subject from .utils import name_generator def mock_NWBFile( session_description: str = 'session_description', identifier: Optional[str] = None, session_start_time: datetime = datetime(1970, 1, 1, tzinfo=tzlocal()), **kwargs ): return NWBFile( session_description=session_description, identifier=identifier or str(uuid4()), session_start_time=session_start_time, **kwargs ) def mock_Subject( age: Optional[str] = "P50D", description: str = "this is a mock mouse.", sex: Optional[str] = "F", subject_id: Optional[str] = None, nwbfile: Optional[NWBFile] = None, ): subject = Subject( age=age, description=description, sex=sex, subject_id=subject_id or name_generator("subject"), ) if nwbfile is not None: nwbfile.subject = subject return subject ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/mock/icephys.py0000644000175100001730000001706514467767506020667 0ustar00runnerdockerfrom typing import Optional import numpy as np from pynwb.icephys import ( IntracellularElectrode, VoltageClampSeries, VoltageClampStimulusSeries, IntracellularRecordingsTable, CurrentClampSeries, CurrentClampStimulusSeries, IZeroClampSeries, ) from .utils import name_generator from .device import mock_Device from ... import NWBFile from ...device import Device def mock_IntracellularElectrode( name: Optional[str] = None, description: str = "description", device: Optional[Device] = None, nwbfile: Optional[NWBFile] = None, ) -> IntracellularElectrode: intracellular_electrode = IntracellularElectrode( name=name or name_generator("IntracellularElectrode"), description=description, device=device or mock_Device(nwbfile=nwbfile), ) if nwbfile is not None: nwbfile.add_icephys_electrode(intracellular_electrode) return intracellular_electrode def mock_VoltageClampStimulusSeries( name: Optional[str] = None, data=None, rate: float = 100_000., electrode: Optional[IntracellularElectrode] = None, gain: float = 0.02, timestamps=None, starting_time: Optional[float] = None, nwbfile: Optional[NWBFile] = None, ) -> VoltageClampStimulusSeries: voltage_clamp_stimulus_series = VoltageClampStimulusSeries( name=name or name_generator("VoltageClampStimulusSeries"), data=data or np.ones((30,)), rate=None if timestamps else rate, electrode=electrode or mock_IntracellularElectrode(nwbfile=nwbfile), gain=gain, timestamps=timestamps, starting_time=starting_time, ) if nwbfile is not None: nwbfile.add_stimulus(voltage_clamp_stimulus_series) return voltage_clamp_stimulus_series def mock_VoltageClampSeries( name: Optional[str] = None, data=None, conversion: float = 1.0, resolution: float = np.nan, starting_time: Optional[float] = None, rate: Optional[float] = 100_000.0, electrode: Optional[IntracellularElectrode] = None, gain: float = 0.02, capacitance_slow: float = 100e-12, resistance_comp_correction: float = 70.0, nwbfile: Optional[NWBFile] = None, ) -> VoltageClampSeries: voltage_clamp_series = VoltageClampSeries( name=name if name is not None else name_generator("VoltageClampSeries"), data=data if data is not None else np.ones((30,)), conversion=conversion, resolution=resolution, starting_time=starting_time, rate=rate, electrode=electrode or mock_IntracellularElectrode(nwbfile=nwbfile), gain=gain, capacitance_slow=capacitance_slow, resistance_comp_correction=resistance_comp_correction, ) if nwbfile is not None: nwbfile.add_acquisition(voltage_clamp_series) return voltage_clamp_series def mock_CurrentClampSeries( name: Optional[str] = None, data=None, electrode: Optional[IntracellularElectrode] = None, gain: float = 0.02, stimulus_description: str = "N/A", bias_current=None, bridge_balance=None, capacitance_compensation=None, resolution=-1.0, conversion=1.0, timestamps=None, starting_time: Optional[float] = None, rate: Optional[float] = 100_000., comments: str = "no comments", description: str = "no description", control=None, control_description=None, sweep_number=None, offset=0.0, unit: str = "volts", nwbfile: Optional[NWBFile] = None, ) -> CurrentClampSeries: current_clamp_series = CurrentClampSeries( name=name if name is not None else name_generator("CurrentClampSeries"), data=data if data is not None else np.ones((30,)), electrode=electrode or mock_IntracellularElectrode(nwbfile=nwbfile), gain=gain, stimulus_description=stimulus_description, bias_current=bias_current, bridge_balance=bridge_balance, capacitance_compensation=capacitance_compensation, resolution=resolution, conversion=conversion, timestamps=timestamps, starting_time=starting_time, rate=rate, comments=comments, description=description, control=control, control_description=control_description, sweep_number=sweep_number, offset=offset, unit=unit, ) if nwbfile is not None: nwbfile.add_acquisition(current_clamp_series) return current_clamp_series def mock_CurrentClampStimulusSeries( name: Optional[str] = None, data=None, electrode=None, gain=0.02, stimulus_description="N/A", resolution=-1.0, conversion=1.0, timestamps=None, starting_time=None, rate=100_000., comments="no comments", description="no description", control=None, control_description=None, sweep_number=None, offset=0.0, unit="amperes", nwbfile: Optional[NWBFile] = None, ) -> CurrentClampStimulusSeries: current_clamp_stimulus_series = CurrentClampStimulusSeries( name=name or name_generator("CurrentClampStimulusSeries"), data=data if data is not None else np.ones((30,)), electrode=electrode or mock_IntracellularElectrode(nwbfile=nwbfile), gain=gain, stimulus_description=stimulus_description, resolution=resolution, conversion=conversion, timestamps=timestamps, starting_time=starting_time, rate=rate, comments=comments, description=description, control=control, control_description=control_description, sweep_number=sweep_number, offset=offset, unit=unit, ) if nwbfile is not None: nwbfile.add_stimulus(current_clamp_stimulus_series) return current_clamp_stimulus_series def mock_IZeroClampSeries( name: Optional[str] = None, data=None, electrode: Optional[IntracellularElectrode] = None, gain=.02, stimulus_description="N/A", resolution=-1.0, conversion=1.0, timestamps=None, starting_time=None, rate=100_000., comments="no comments", description="no description", control=None, control_description=None, sweep_number=None, offset=0.0, unit="volts", nwbfile: Optional[NWBFile] = None, ) -> IZeroClampSeries: izero_clamp_series = IZeroClampSeries( name=name or name_generator("IZeroClampSeries"), data=data if data is not None else np.ones((30,)), electrode=electrode or mock_IntracellularElectrode(nwbfile=nwbfile), gain=gain, stimulus_description=stimulus_description, resolution=resolution, conversion=conversion, timestamps=timestamps, starting_time=starting_time, rate=rate, comments=comments, description=description, control=control, control_description=control_description, sweep_number=sweep_number, offset=offset, unit=unit, ) if nwbfile is not None: nwbfile.add_acquisition(izero_clamp_series) return izero_clamp_series def mock_IntracellularRecordingsTable( n_rows: int = 5, nwbfile: Optional[NWBFile] = None ) -> IntracellularRecordingsTable: irt = IntracellularRecordingsTable() for _ in range(n_rows): electrode = mock_IntracellularElectrode(nwbfile=nwbfile) irt.add_recording( electrode=electrode, stimulus=mock_VoltageClampStimulusSeries(electrode=electrode, nwbfile=nwbfile), response=mock_VoltageClampSeries(electrode=electrode, nwbfile=nwbfile), ) if nwbfile is not None: nwbfile.intracellular_recordings = irt return irt ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/mock/ogen.py0000644000175100001730000000401114467767506020136 0ustar00runnerdockerfrom typing import Optional import numpy as np from ... import NWBFile from ...device import Device from ...ogen import OptogeneticStimulusSite, OptogeneticSeries from .device import mock_Device from .utils import name_generator def mock_OptogeneticStimulusSite( name: Optional[str] = None, device: Optional[Device] = None, description: str = "optogenetic stimulus site", excitation_lambda: float = 500., location: str = "part of the brain", nwbfile: Optional[NWBFile] = None, ) -> OptogeneticStimulusSite: optogenetic_stimulus_site = OptogeneticStimulusSite( name=name or name_generator("OptogeneticStimulusSite"), device=device or mock_Device(nwbfile=nwbfile), description=description, excitation_lambda=excitation_lambda, location=location ) if nwbfile is not None: nwbfile.add_ogen_site(optogenetic_stimulus_site) return optogenetic_stimulus_site def mock_OptogeneticSeries( name: Optional[str] = None, data=None, site: Optional[OptogeneticStimulusSite] = None, resolution: float = -1.0, conversion: float = 1.0, timestamps=None, starting_time: Optional[float] = None, rate: Optional[float] = 10.0, comments: str = "no comments", description: str = "no description", control=None, control_description=None, nwbfile: Optional[NWBFile] = None, ) -> OptogeneticSeries: optogenetic_series = OptogeneticSeries( name=name or name_generator("OptogeneticSeries"), data=data if data is not None else np.array([1, 2, 3, 4]), site=site or mock_OptogeneticStimulusSite(nwbfile=nwbfile), resolution=resolution, conversion=conversion, timestamps=timestamps, starting_time=starting_time, rate=rate, comments=comments, description=description, control=control, control_description=control_description, ) if nwbfile is not None: nwbfile.add_acquisition(optogenetic_series) return optogenetic_series ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/mock/ophys.py0000644000175100001730000002361114467767506020357 0ustar00runnerdockerfrom typing import Optional, Sequence import numpy as np from hdmf.common.table import DynamicTableRegion from ... import NWBFile from ...device import Device from ...ophys import ( RoiResponseSeries, OpticalChannel, ImagingPlane, OnePhotonSeries, TwoPhotonSeries, PlaneSegmentation, ImageSegmentation, DfOverF, Fluorescence, ) from .device import mock_Device from .utils import name_generator def mock_OpticalChannel( name: Optional[str] = None, description: str = "description", emission_lambda: float = 500.0, nwbfile: Optional[NWBFile] = None, ) -> OpticalChannel: optical_channel = OpticalChannel( name=name or name_generator("OpticalChannel"), description=description, emission_lambda=emission_lambda, ) if nwbfile is not None: mock_ImagingPlane(nwbfile=nwbfile, optical_channel=optical_channel) return optical_channel def mock_ImagingPlane( name: Optional[str] = None, optical_channel: Optional[OpticalChannel] = None, description: str = "description", device: Optional[Device] = None, excitation_lambda: float = 500.0, indicator: str = "indicator", location: str = "unknown", imaging_rate: float = 30.0, manifold=None, conversion: float = 1.0, unit: str = "meters", reference_frame=None, origin_coords=None, origin_coords_unit: str = "meters", grid_spacing=None, grid_spacing_unit: str = "meters", nwbfile: Optional[NWBFile] = None, ) -> ImagingPlane: imaging_plane = ImagingPlane( name=name or name_generator("ImagingPlane"), optical_channel=optical_channel or mock_OpticalChannel(nwbfile=nwbfile), description=description, device=device or mock_Device(nwbfile=nwbfile), excitation_lambda=excitation_lambda, indicator=indicator, location=location, imaging_rate=imaging_rate, manifold=manifold, conversion=conversion, unit=unit, reference_frame=reference_frame, origin_coords=origin_coords, origin_coords_unit=origin_coords_unit, grid_spacing=grid_spacing, grid_spacing_unit=grid_spacing_unit, ) if nwbfile is not None: if "ophys" not in nwbfile.processing: nwbfile.create_processing_module("ophys", "ophys") nwbfile.add_imaging_plane(imaging_plane) return imaging_plane def mock_OnePhotonSeries( name: Optional[str] = None, imaging_plane: Optional[ImagingPlane] = None, data=None, rate: Optional[float] = 50.0, unit: str = "n.a.", exposure_time=None, binning=None, power=None, intensity=None, format=None, pmt_gain=None, scan_line_rate=None, external_file=None, starting_frame=[0], bits_per_pixel=None, dimension=None, resolution=-1.0, conversion=1.0, offset=0.0, timestamps=None, starting_time=None, comments="no comments", description="no description", control=None, control_description=None, device=None, nwbfile: Optional[NWBFile] = None, ) -> OnePhotonSeries: one_photon_series = OnePhotonSeries( name=name if name is not None else name_generator("OnePhotonSeries"), imaging_plane=imaging_plane or mock_ImagingPlane(nwbfile=nwbfile), data=data if data is not None else np.ones((20, 5, 5)), unit=unit, exposure_time=exposure_time, binning=binning, power=power, intensity=intensity, format=format, pmt_gain=pmt_gain, scan_line_rate=scan_line_rate, external_file=external_file, starting_frame=starting_frame, bits_per_pixel=bits_per_pixel, dimension=dimension, resolution=resolution, conversion=conversion, timestamps=timestamps, starting_time=starting_time, rate=rate, comments=comments, description=description, control=control, control_description=control_description, device=device, ) if nwbfile is not None: nwbfile.add_acquisition(one_photon_series) return one_photon_series def mock_TwoPhotonSeries( name: Optional[str] = None, imaging_plane: Optional[ImagingPlane] = None, data=None, rate=50.0, unit="n.a.", format=None, field_of_view=None, pmt_gain=None, scan_line_rate=None, external_file=None, starting_frame=[0], bits_per_pixel=None, dimension=None, resolution=-1.0, conversion=1.0, timestamps=None, starting_time=None, comments="no comments", description="no description", control=None, control_description=None, device=None, nwbfile: Optional[NWBFile] = None, ) -> TwoPhotonSeries: two_photon_series = TwoPhotonSeries( name=name if name is not None else name_generator("TwoPhotonSeries"), imaging_plane=imaging_plane or mock_ImagingPlane(nwbfile=nwbfile), data=data if data is not None else np.ones((20, 5, 5)), unit=unit, format=format, field_of_view=field_of_view, pmt_gain=pmt_gain, scan_line_rate=scan_line_rate, external_file=external_file, starting_frame=starting_frame, bits_per_pixel=bits_per_pixel, dimension=dimension, resolution=resolution, conversion=conversion, timestamps=timestamps, starting_time=starting_time, rate=rate, comments=comments, description=description, control=control, control_description=control_description, device=device, ) if nwbfile is not None: nwbfile.add_acquisition(two_photon_series) return two_photon_series def mock_PlaneSegmentation( description: str = "no description", imaging_plane: Optional[ImagingPlane] = None, name: Optional[str] = None, reference_images=None, n_rois: int = 5, nwbfile: Optional[NWBFile] = None, ) -> PlaneSegmentation: plane_segmentation = PlaneSegmentation( description=description, imaging_plane=imaging_plane or mock_ImagingPlane(nwbfile=nwbfile), name=name if name is not None else name_generator("PlaneSegmentation"), reference_images=reference_images, ) for _ in range(n_rois): plane_segmentation.add_roi(image_mask=np.zeros((10, 10))) if nwbfile is not None: if "ophys" not in nwbfile.processing: nwbfile.create_processing_module("ophys", "ophys") nwbfile.processing["ophys"].add(plane_segmentation) return plane_segmentation def mock_ImageSegmentation( plane_segmentations: Optional[Sequence[PlaneSegmentation]] = None, name: Optional[str] = None, nwbfile: Optional[NWBFile] = None ) -> ImageSegmentation: image_segmentation = ImageSegmentation( plane_segmentations=plane_segmentations or [mock_PlaneSegmentation(nwbfile=nwbfile)], name=name or name_generator("ImageSegmentation"), ) if nwbfile is not None: if "ophys" not in nwbfile.processing: nwbfile.create_processing_module("ophys", "ophys") nwbfile.processing["ophys"].add(image_segmentation) return image_segmentation def mock_RoiResponseSeries( name: Optional[str] = None, data=None, unit: str = "n.a.", rois=None, resolution=-1.0, conversion=1.0, timestamps=None, starting_time=None, rate=50.0, comments="no comments", description="no description", control=None, control_description=None, n_rois=None, plane_segmentation: Optional[PlaneSegmentation] = None, nwbfile: Optional[NWBFile] = None, ) -> RoiResponseSeries: if data is not None: if n_rois is not None and n_rois != data.shape[1]: raise ValueError("Argument conflict: n_rois does not match second dimension of data.") n_rois = data.shape[1] else: n_rois = 5 roi_response_series = RoiResponseSeries( name=name if name is not None else name_generator("RoiResponseSeries"), data=data if data is not None else np.ones((30, n_rois)), unit=unit, rois=rois or DynamicTableRegion( name="rois", description="rois", table=plane_segmentation or mock_PlaneSegmentation(n_rois=n_rois, nwbfile=nwbfile), data=list(range(n_rois)), ), resolution=resolution, conversion=conversion, timestamps=timestamps, starting_time=starting_time, rate=rate, comments=comments, description=description, control=control, control_description=control_description, ) if nwbfile is not None: if "ophys" not in nwbfile.processing: nwbfile.create_processing_module("ophys", "ophys") nwbfile.processing["ophys"].add(roi_response_series) return roi_response_series def mock_DfOverF( roi_response_series: Optional[RoiResponseSeries] = None, name: Optional[str] = None, nwbfile: Optional[NWBFile] = None ) -> DfOverF: df_over_f = DfOverF( roi_response_series=roi_response_series or [mock_RoiResponseSeries(nwbfile=nwbfile)], name=name if name is not None else name_generator("DfOverF"), ) if nwbfile is not None: if "ophys" not in nwbfile.processing: nwbfile.create_processing_module("ophys", "ophys") nwbfile.processing["ophys"].add(df_over_f) return df_over_f def mock_Fluorescence( roi_response_series: Optional[Sequence[RoiResponseSeries]] = None, name: Optional[str] = None, nwbfile: Optional[NWBFile] = None, ) -> Fluorescence: fluorescence = Fluorescence( roi_response_series=roi_response_series or [mock_RoiResponseSeries(nwbfile=nwbfile)], name=name if name is not None else name_generator("Fluorescence"), ) if nwbfile is not None: if "ophys" not in nwbfile.processing: nwbfile.create_processing_module("ophys", "ophys") nwbfile.processing["ophys"].add(fluorescence) return fluorescence ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/mock/utils.py0000644000175100001730000000124114467767506020350 0ustar00runnerdockername_generator_registry = dict() def name_generator(name): """ Returns unique names of neurodata types using an incrementing number. The first time you pass "TimeSeries" it returns "TimeSeries". The second time, it returns "TimeSeries2", the third time it returns "TimeSeries3", etc. Parameters ---------- name: str name of neurodata_type, e.g. TimeSeries Returns ------- name of neurodata_object: str """ if name not in name_generator_registry: name_generator_registry[name] = 1 return name else: name_generator_registry[name] += 1 return f"{name}{name_generator_registry[name]}" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/testh5io.py0000644000175100001730000003665614467767506020045 0ustar00runnerdockerfrom datetime import datetime from dateutil.tz import tzlocal, tzutc import os from abc import ABCMeta, abstractmethod import warnings from pynwb import NWBFile, NWBHDF5IO, validate as pynwb_validate from .utils import remove_test_file from hdmf.backends.warnings import BrokenLinkWarning from hdmf.build.warnings import MissingRequiredBuildWarning class NWBH5IOMixin(metaclass=ABCMeta): """ Mixin class for methods to run a roundtrip test writing an NWB file with an Container and reading the Container from the NWB file. The setUp, test_roundtrip, and tearDown methods will be run by unittest. The abstract methods setUpContainer, addContainer, and getContainer needs to be implemented by classes that include this mixin. Example:: class TestMyContainerIO(NWBH5IOMixin, TestCase): def setUpContainer(self): # return a test Container to read/write def addContainer(self, nwbfile): # add the test Container to an NWB file def getContainer(self, nwbfile): # return the test Container from an NWB file This code is adapted from hdmf.testing.H5RoundTripMixin. """ def setUp(self): self.container = self.setUpContainer() self.start_time = datetime(1971, 1, 1, 12, tzinfo=tzutc()) self.create_date = datetime(2018, 4, 15, 12, tzinfo=tzlocal()) self.container_type = self.container.__class__.__name__ self.filename = 'test_%s.nwb' % self.container_type self.export_filename = 'test_export_%s.nwb' % self.container_type self.reader = None self.export_reader = None def tearDown(self): if self.reader is not None: self.reader.close() if self.export_reader is not None: self.export_reader.close() remove_test_file(self.filename) remove_test_file(self.export_filename) @abstractmethod def setUpContainer(self): """ Should return the test Container to read/write """ raise NotImplementedError('Cannot run test unless setUpContainer is implemented') def test_roundtrip(self): """Test whether the read Container has the same contents as the original Container and validate the file. """ self.read_container = self.roundtripContainer() self.assertIsNotNone(str(self.container)) # added as a test to make sure printing works self.assertIsNotNone(str(self.read_container)) # make sure we get a completely new object self.assertNotEqual(id(self.container), id(self.read_container)) # make sure the object ID is preserved self.assertIs(self.read_nwbfile.objects[self.container.object_id], self.read_container) self.assertContainerEqual(self.read_container, self.container) def test_roundtrip_export(self): """ Test whether the test Container read from an exported file has the same contents as the original test Container and validate the file """ self.read_container = self.roundtripExportContainer() self.assertIsNotNone(str(self.read_container)) # added as a test to make sure printing works # make sure we get a completely new object self.assertNotEqual(id(self.container), id(self.read_container)) # make sure the object ID is preserved self.assertIs(self.read_exported_nwbfile.objects[self.container.object_id], self.read_container) self.assertContainerEqual(self.read_container, self.container, ignore_hdmf_attrs=True) def roundtripContainer(self, cache_spec=False): """Add the Container to an NWBFile, write it to file, read the file, and return the Container from the file. """ session_description = 'a file to test writing and reading a %s' % self.container_type identifier = 'TEST_%s' % self.container_type nwbfile = NWBFile( session_description=session_description, identifier=identifier, session_start_time=self.start_time, file_create_date=self.create_date ) self.addContainer(nwbfile) with warnings.catch_warnings(record=True) as ws: with NWBHDF5IO(self.filename, mode='w') as write_io: write_io.write(nwbfile, cache_spec=cache_spec) self.validate() self.reader = NWBHDF5IO(self.filename, mode='r') self.read_nwbfile = self.reader.read() if ws: for w in ws: if issubclass(w.category, (MissingRequiredBuildWarning, BrokenLinkWarning)): raise Exception('%s: %s' % (w.category.__name__, w.message)) else: warnings.showwarning(w.message, w.category, w.filename, w.lineno, w.file, w.line) try: return self.getContainer(self.read_nwbfile) except Exception as e: self.reader.close() self.reader = None raise e def roundtripExportContainer(self, cache_spec=False): """ Add the test Container to an NWBFile, write it to file, read the file, export the read NWBFile to another file, and return the test Container from the file """ self.roundtripContainer(cache_spec=cache_spec) # self.read_nwbfile is now set with warnings.catch_warnings(record=True) as ws: NWBHDF5IO.export_io( src_io=self.reader, path=self.export_filename, cache_spec=cache_spec, ) self.validate() self.export_reader = NWBHDF5IO(self.export_filename, mode='r') self.read_exported_nwbfile = self.export_reader.read() if ws: for w in ws: if issubclass(w.category, (MissingRequiredBuildWarning, BrokenLinkWarning)): raise Exception('%s: %s' % (w.category.__name__, w.message)) else: warnings.showwarning(w.message, w.category, w.filename, w.lineno, w.file, w.line) try: return self.getContainer(self.read_exported_nwbfile) except Exception as e: self.export_reader.close() self.export_reader = None raise e @abstractmethod def addContainer(self, nwbfile): """ Should add the test Container to the given NWBFile """ raise NotImplementedError('Cannot run test unless addContainer is implemented') @abstractmethod def getContainer(self, nwbfile): """ Should return the test Container from the given NWBFile """ raise NotImplementedError('Cannot run test unless getContainer is implemented') def validate(self): """ Validate the created files """ if os.path.exists(self.filename): with NWBHDF5IO(self.filename, mode='r') as io: errors = pynwb_validate(io) if errors: for err in errors: raise Exception(err) if os.path.exists(self.export_filename): with NWBHDF5IO(self.filename, mode='r') as io: errors = pynwb_validate(io) if errors: for err in errors: raise Exception(err) class AcquisitionH5IOMixin(NWBH5IOMixin): """ Mixin class for methods to run a roundtrip test writing an NWB file with an Container as an acquisition and reading the Container as an acquisition from the NWB file. The setUp, test_roundtrip, and tearDown methods will be run by unittest. The abstract method setUpContainer needs to be implemented by classes that include this mixin. Example:: class TestMyContainerIO(NWBH5IOMixin, TestCase): def setUpContainer(self): # return a test Container to read/write This code is adapted from hdmf.testing.H5RoundTripMixin. """ def addContainer(self, nwbfile): ''' Add an NWBDataInterface object to the file as an acquisition ''' nwbfile.add_acquisition(self.container) def getContainer(self, nwbfile): ''' Get the NWBDataInterface object from the file ''' return nwbfile.get_acquisition(self.container.name) class NWBH5IOFlexMixin(metaclass=ABCMeta): """ Mixin class that includes methods to run a flexible roundtrip test. The setUp, test_roundtrip, and tearDown methods will be run by unittest. The abstract methods getContainerType, addContainer, and getContainer must be implemented by classes that includethis mixin. Example:: class TestMyContainerIO(NWBH5IOFlexMixin, TestCase): def getContainerType(self): # return the name of the type of Container being tested, for test ID purposes def addContainer(self): # add the test Container to the test NWB file def getContainer(self, nwbfile): # return the test Container from an NWB file This class is more flexible than NWBH5IOMixin and should be used for new roundtrip tests. This code is adapted from hdmf.testing.H5RoundTripMixin. """ def setUp(self): container_type = self.getContainerType().replace(" ", "_") session_description = 'A file to test writing and reading a %s' % container_type identifier = 'TEST_%s' % container_type session_start_time = datetime(1971, 1, 1, 12, tzinfo=tzutc()) self.nwbfile = NWBFile( session_description=session_description, identifier=identifier, session_start_time=session_start_time, ) self.addContainer() self.container = self.getContainer(self.nwbfile) self.filename = 'test_%s.nwb' % container_type self.export_filename = 'test_export_%s.nwb' % container_type self.reader = None self.export_reader = None def tearDown(self): if self.reader is not None: self.reader.close() if self.export_reader is not None: self.export_reader.close() remove_test_file(self.filename) remove_test_file(self.export_filename) def getContainerType() -> str: """Return the name of the type of Container being tested, for test ID purposes.""" raise NotImplementedError('Cannot run test unless getContainerType is implemented.') @abstractmethod def addContainer(self): """Add the test Container to the NWBFile. The NWBFile is accessible from self.nwbfile. The Container should be accessible from getContainer(self.nwbfile). """ raise NotImplementedError('Cannot run test unless addContainer is implemented.') @abstractmethod def getContainer(self, nwbfile: NWBFile): """Return the test Container from the given NWBFile.""" raise NotImplementedError('Cannot run test unless getContainer is implemented.') def test_roundtrip(self): """Test whether the read Container has the same contents as the original Container and validate the file. """ self.read_container = self.roundtripContainer() self.assertIsNotNone(str(self.container)) # added as a test to make sure printing works self.assertIsNotNone(str(self.read_container)) # make sure we get a completely new object self.assertNotEqual(id(self.container), id(self.read_container)) # make sure the object ID is preserved self.assertIs(self.read_nwbfile.objects[self.container.object_id], self.read_container) self.assertContainerEqual(self.read_container, self.container) def test_roundtrip_export(self): """ Test whether the test Container read from an exported file has the same contents as the original test Container and validate the file. """ self.read_container = self.roundtripExportContainer() # this container is read from the exported file self.assertIsNotNone(str(self.read_container)) # added as a test to make sure printing works # make sure we get a completely new object self.assertNotEqual(id(self.container), id(self.read_container)) # make sure the object ID is preserved self.assertIs(self.read_exported_nwbfile.objects[self.container.object_id], self.read_container) self.assertContainerEqual(self.read_container, self.container, ignore_hdmf_attrs=True) def roundtripContainer(self, cache_spec=False): """Write the file, validate the file, read the file, and return the Container from the file. """ # catch all warnings with warnings.catch_warnings(record=True) as ws: with NWBHDF5IO(self.filename, mode='w') as write_io: write_io.write(self.nwbfile, cache_spec=cache_spec) self.validate() # this is not closed until tearDown() or an exception from self.getContainer below self.reader = NWBHDF5IO(self.filename, mode='r') self.read_nwbfile = self.reader.read() # parse warnings and raise exceptions for certain types of warnings if ws: for w in ws: if issubclass(w.category, (MissingRequiredBuildWarning, BrokenLinkWarning)): raise Exception('%s: %s' % (w.category.__name__, w.message)) else: warnings.warn(w.message, w.category) try: return self.getContainer(self.read_nwbfile) except Exception as e: self.reader.close() self.reader = None raise e def roundtripExportContainer(self, cache_spec=False): """ Roundtrip the container, then export the read NWBFile to a new file, validate the files, and return the test Container from the file. """ # write and read the file. self.reader will be set self.roundtripContainer(cache_spec=cache_spec) # catch all warnings with warnings.catch_warnings(record=True) as ws: NWBHDF5IO.export_io( src_io=self.reader, path=self.export_filename, cache_spec=cache_spec, ) self.validate() # this is not closed until tearDown() or an exception from self.getContainer below self.export_reader = NWBHDF5IO(self.export_filename, mode='r') self.read_exported_nwbfile = self.export_reader.read() # parse warnings and raise exceptions for certain types of warnings if ws: for w in ws: if issubclass(w.category, (MissingRequiredBuildWarning, BrokenLinkWarning)): raise Exception('%s: %s' % (w.category.__name__, w.message)) else: warnings.warn(w.message, w.category) try: return self.getContainer(self.read_exported_nwbfile) except Exception as e: self.export_reader.close() self.export_reader = None raise e def validate(self): """Validate the created files.""" if os.path.exists(self.filename): with NWBHDF5IO(self.filename, mode='r') as io: errors = pynwb_validate(io) if errors: raise Exception("\n".join(errors)) if os.path.exists(self.export_filename): with NWBHDF5IO(self.filename, mode='r') as io: errors = pynwb_validate(io) if errors: raise Exception("\n".join(errors)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/testing/utils.py0000644000175100001730000000070014467767506017416 0ustar00runnerdockerimport os def remove_test_file(path): """A helper function for removing intermediate test files This checks if the environment variable CLEAN_NWB has been set to False before removing the file. If CLEAN_NWB is set to False, it does not remove the file. """ clean_flag_set = os.getenv('CLEAN_NWB', True) not in ('False', 'false', 'FALSE', '0', 0, False) if os.path.exists(path) and clean_flag_set: os.remove(path) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/src/pynwb/validate.py0000644000175100001730000002173314467767506016403 0ustar00runnerdocker"""Command line tool to Validate an NWB file against a namespace.""" import sys from argparse import ArgumentParser from typing import Tuple, List, Dict, Optional from hdmf.spec import NamespaceCatalog from hdmf.build import BuildManager from hdmf.build import TypeMap as TypeMap from hdmf.utils import docval, getargs from hdmf.backends.io import HDMFIO from hdmf.validate import ValidatorMap from pynwb import CORE_NAMESPACE from pynwb.spec import NWBDatasetSpec, NWBGroupSpec, NWBNamespace def _print_errors(validation_errors: list): if validation_errors: print(" - found the following errors:", file=sys.stderr) for err in validation_errors: print(str(err), file=sys.stderr) else: print(" - no errors found.") def _validate_helper(io: HDMFIO, namespace: str = CORE_NAMESPACE) -> list: builder = io.read_builder() validator = ValidatorMap(io.manager.namespace_catalog.get_namespace(name=namespace)) return validator.validate(builder) def _get_cached_namespaces_to_validate( path: str, driver: Optional[str] = None ) -> Tuple[List[str], BuildManager, Dict[str, str]]: """ Determine the most specific namespace(s) that are cached in the given NWBFile that can be used for validation. Example ------- The following example illustrates how we can use this function to validate against namespaces cached in a file. This is useful, e.g., when a file was created using an extension >>> from pynwb import validate >>> from pynwb.validate import _get_cached_namespaces_to_validate >>> path = "my_nwb_file.nwb" >>> validate_namespaces, manager, cached_namespaces = _get_cached_namespaces_to_validate(path) >>> with NWBHDF5IO(path, "r", manager=manager) as reader: >>> errors = [] >>> for ns in validate_namespaces: >>> errors += validate(io=reader, namespace=ns) :param path: Path for the NWB file :return: Tuple with: - List of strings with the most specific namespace(s) to use for validation. - BuildManager object for opening the file for validation - Dict with the full result from NWBHDF5IO.load_namespaces """ from . import NWBHDF5IO # TODO: modularize to avoid circular import catalog = NamespaceCatalog( group_spec_cls=NWBGroupSpec, dataset_spec_cls=NWBDatasetSpec, spec_namespace_cls=NWBNamespace ) namespace_dependencies = NWBHDF5IO.load_namespaces(namespace_catalog=catalog, path=path, driver=driver) # Determine which namespaces are the most specific (i.e. extensions) and validate against those candidate_namespaces = set(namespace_dependencies.keys()) for namespace_dependency in namespace_dependencies: candidate_namespaces -= namespace_dependencies[namespace_dependency].keys() # TODO: remove this workaround for issue https://github.com/NeurodataWithoutBorders/pynwb/issues/1357 candidate_namespaces.discard("hdmf-experimental") # remove validation of hdmf-experimental for now cached_namespaces = sorted(candidate_namespaces) if len(cached_namespaces) > 0: type_map = TypeMap(namespaces=catalog) manager = BuildManager(type_map=type_map) else: manager = None return cached_namespaces, manager, namespace_dependencies @docval( { "name": "io", "type": HDMFIO, "doc": "An open IO to an NWB file.", "default": None, }, # For back-compatability { "name": "namespace", "type": str, "doc": "A specific namespace to validate against.", "default": None, }, # Argument order is for back-compatability { "name": "paths", "type": list, "doc": "List of NWB file paths.", "default": None, }, { "name": "use_cached_namespaces", "type": bool, "doc": "Whether to use namespaces cached within the file for validation.", "default": True, }, { "name": "verbose", "type": bool, "doc": "Whether or not to print messages to stdout.", "default": False, }, { "name": "driver", "type": str, "doc": "Driver for h5py to use when opening the HDF5 file.", "default": None, }, returns="Validation errors in the file.", rtype=(list, (list, bool)), is_method=False, ) def validate(**kwargs): """Validate NWB file(s) against a namespace or its cached namespaces.""" from . import NWBHDF5IO # TODO: modularize to avoid circular import io, paths, use_cached_namespaces, namespace, verbose, driver = getargs( "io", "paths", "use_cached_namespaces", "namespace", "verbose", "driver", kwargs ) assert io != paths, "Both 'io' and 'paths' were specified! Please choose only one." if io is not None: validation_errors = _validate_helper(io=io, namespace=namespace or CORE_NAMESPACE) return validation_errors status = 0 validation_errors = list() for path in paths: namespaces_to_validate = [] namespace_message = "PyNWB namespace information" io_kwargs = dict(path=path, mode="r", driver=driver) if use_cached_namespaces: cached_namespaces, manager, namespace_dependencies = _get_cached_namespaces_to_validate( path=path, driver=driver ) io_kwargs.update(manager=manager) if any(cached_namespaces): namespaces_to_validate = cached_namespaces namespace_message = "cached namespace information" else: namespaces_to_validate = [CORE_NAMESPACE] if verbose: print( f"The file {path} has no cached namespace information. Falling back to {namespace_message}.", file=sys.stderr, ) else: namespaces_to_validate = [CORE_NAMESPACE] if namespace is not None: if namespace in namespaces_to_validate: namespaces_to_validate = [namespace] elif use_cached_namespaces and namespace in namespace_dependencies: # validating against a dependency for namespace_dependency in namespace_dependencies: if namespace in namespace_dependencies[namespace_dependency]: status = 1 print( f"The namespace '{namespace}' is included by the namespace " f"'{namespace_dependency}'. Please validate against that namespace instead.", file=sys.stderr, ) else: status = 1 print( f"The namespace '{namespace}' could not be found in {namespace_message} as only " f"{namespaces_to_validate} is present.", file=sys.stderr, ) if status == 1: continue with NWBHDF5IO(**io_kwargs) as io: for validation_namespace in namespaces_to_validate: if verbose: print(f"Validating {path} against {namespace_message} using namespace '{validation_namespace}'.") validation_errors += _validate_helper(io=io, namespace=validation_namespace) return validation_errors, status def validate_cli(): """CLI wrapper around pynwb.validate.""" parser = ArgumentParser( description="Validate an NWB file", epilog="If --ns is not specified, validate against all namespaces in the NWB file.", ) # Special arg specific to CLI parser.add_argument( "-lns", "--list-namespaces", dest="list_namespaces", action="store_true", help="List the available namespaces and exit.", ) # Common args to the API validate parser.add_argument("paths", type=str, nargs="+", help="NWB file paths") parser.add_argument("-n", "--ns", type=str, help="the namespace to validate against") feature_parser = parser.add_mutually_exclusive_group(required=False) feature_parser.add_argument( "--no-cached-namespace", dest="no_cached_namespace", action="store_true", help="Use the PyNWB loaded namespace (true) or use the cached namespace (false; default).", ) parser.set_defaults(no_cached_namespace=False) args = parser.parse_args() status = 0 if args.list_namespaces: for path in args.paths: cached_namespaces, _, _ = _get_cached_namespaces_to_validate(path=path) print("\n".join(cached_namespaces)) else: validation_errors, validation_status = validate( paths=args.paths, use_cached_namespaces=not args.no_cached_namespace, namespace=args.ns, verbose=True ) if not validation_status: _print_errors(validation_errors=validation_errors) status = status or validation_status or (validation_errors is not None and len(validation_errors) > 0) sys.exit(status) if __name__ == "__main__": # pragma: no cover validate_cli() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5420275 pynwb-2.5.0/src/pynwb.egg-info/0000755000175100001730000000000014467767767015735 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397558.0 pynwb-2.5.0/src/pynwb.egg-info/PKG-INFO0000644000175100001730000002142114467767766017031 0ustar00runnerdockerMetadata-Version: 2.1 Name: pynwb Version: 2.5.0 Summary: Package for working with Neurodata stored in the NWB format Home-page: https://github.com/NeurodataWithoutBorders/pynwb Author: Andrew Tritt Author-email: ajtritt@lbl.gov License: BSD Keywords: Neuroscience python HDF HDF5 cross-platform open-data data-format open-source open-science reproducible-research PyNWB NWB NWB:N NeurodataWithoutBorders Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: License :: OSI Approved :: BSD License Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research Classifier: Operating System :: Microsoft :: Windows Classifier: Operating System :: MacOS Classifier: Operating System :: Unix Classifier: Topic :: Scientific/Engineering :: Medical Science Apps. Requires-Python: >=3.8 Description-Content-Type: text/x-rst; charset=UTF-8 .. image:: docs/source/figures/logo_pynwb.png :width: 200px PyNWB is a Python package for working with NWB files. The PyNWB documentation can be found at https://pynwb.readthedocs.io Latest Release ============== .. image:: https://badge.fury.io/py/pynwb.svg :target: https://badge.fury.io/py/pynwb .. image:: https://anaconda.org/conda-forge/pynwb/badges/version.svg :target: https://anaconda.org/conda-forge/pynwb Code Coverage ============== .. image:: https://github.com/NeurodataWithoutBorders/pynwb/workflows/Run%20coverage/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions?query=workflow%3A%22Run+coverage%22 Overall test coverage .. image:: https://codecov.io/gh/NeurodataWithoutBorders/pynwb/branch/dev/graph/badge.svg :target: https://codecov.io/gh/NeurodataWithoutBorders/pynwb Unit test coverage .. image:: https://codecov.io/gh/NeurodataWithoutBorders/pynwb/branch/dev/graph/badge.svg?flag=unit :target: https://codecov.io/gh/NeurodataWithoutBorders/pynwb Integration test coverage .. image:: https://codecov.io/gh/NeurodataWithoutBorders/pynwb/branch/dev/graph/badge.svg?flag=integration :target: https://codecov.io/gh/NeurodataWithoutBorders/pynwb Overall Health ============== .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_tests.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_tests.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_flake8.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_flake8.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/check_external_links.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/check_external_links.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_inspector_tests.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_inspector_tests.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_all_tests.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/run_all_tests.yml .. image:: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/deploy_release.yml/badge.svg :target: https://github.com/NeurodataWithoutBorders/pynwb/actions/workflows/deploy_release.yml .. image:: https://readthedocs.org/projects/pynwb/badge/?version=latest :target: https://pynwb.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status .. image:: https://img.shields.io/pypi/l/pynwb.svg :target: https://github.com/neurodatawithoutborders/pynwb/blob/dev/license.txt :alt: PyPI - License **Conda** .. image:: https://circleci.com/gh/conda-forge/pynwb-feedstock.svg?style=shield :target: https://circleci.com/gh/conda-forge/pynwb-feedstock :alt: Conda Feedstock Status NWB Format API ============== PyNWB is a Python package for working with NWB files. It provides a high-level API for efficiently working with Neurodata stored in the `NWB format `_. `Neurodata Without Borders (NWB) `_ is a project to develop a unified data format for cellular-based neurophysiology data, focused on the dynamics of groups of neurons measured under a large range of experimental conditions. The NWB team consists of neuroscientists and software developers who recognize that adoption of a unified data format is an important step toward breaking down the barriers to data sharing in neuroscience. Installation ============ See the PyNWB documentation for details https://pynwb.readthedocs.io/en/stable/install_users.html Code of Conduct =============== This project and everyone participating in it is governed by our `code of conduct guidelines <.github/CODE_OF_CONDUCT.rst>`_. By participating, you are expected to uphold this code. Contributing ============ For details on how to contribute to PyNWB see our `contribution guidelines `_. Citing NWB ========== * **Manuscript:** Oliver Rübel, Andrew Tritt, Ryan Ly, Benjamin K Dichter, Satrajit Ghosh, Lawrence Niu, Pamela Baker, Ivan Soltesz, Lydia Ng, Karel Svoboda, Loren Frank, Kristofer E Bouchard. (2022). The Neurodata Without Borders ecosystem for neurophysiological data science. eLife, 11:e78362. doi: https://doi.org/10.7554/eLife.78362 * **RRID:** (PyNWB, RRID:SCR_017452) LICENSE ======= "pynwb" Copyright (c) 2017-2023, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, U.S. Dept. of Energy nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You are under no obligation whatsoever to provide any bug fixes, patches, or upgrades to the features, functionality or performance of the source code ("Enhancements") to anyone; however, if you choose to make your Enhancements available either publicly, or directly to Lawrence Berkeley National Laboratory, without imposing a separate written license agreement for such Enhancements, then you hereby grant the following license: a non-exclusive, royalty-free perpetual license to install, use, modify, prepare derivative works, incorporate into other computer software, distribute, and sublicense such enhancements or derivative works thereof, in binary and source code form. COPYRIGHT ========= "pynwb" Copyright (c) 2017-2023, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. If you have questions about your rights to use or distribute this software, please contact Berkeley Lab's Innovation & Partnerships Office at IPO@lbl.gov. NOTICE. This Software was developed under funding from the U.S. Department of Energy and the U.S. Government consequently retains certain rights. As such, the U.S. Government has been granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software to reproduce, distribute copies to the public, prepare derivative works, and perform publicly and display publicly, and to permit other to do so. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397558.0 pynwb-2.5.0/src/pynwb.egg-info/SOURCES.txt0000644000175100001730000001170614467767766017625 0ustar00runnerdockerLegal.txt MANIFEST.in README.rst environment-ros3.yml license.txt requirements-dev.txt requirements-doc.txt requirements-min.txt requirements.txt setup.cfg setup.py test.py tox.ini versioneer.py src/pynwb/__init__.py src/pynwb/_due.py src/pynwb/_version.py src/pynwb/base.py src/pynwb/behavior.py src/pynwb/core.py src/pynwb/device.py src/pynwb/ecephys.py src/pynwb/epoch.py src/pynwb/file.py src/pynwb/icephys.py src/pynwb/image.py src/pynwb/misc.py src/pynwb/ogen.py src/pynwb/ophys.py src/pynwb/resources.py src/pynwb/retinotopy.py src/pynwb/spec.py src/pynwb/validate.py src/pynwb.egg-info/PKG-INFO src/pynwb.egg-info/SOURCES.txt src/pynwb.egg-info/dependency_links.txt src/pynwb.egg-info/not-zip-safe src/pynwb.egg-info/requires.txt src/pynwb.egg-info/top_level.txt src/pynwb/io/__init__.py src/pynwb/io/base.py src/pynwb/io/behavior.py src/pynwb/io/core.py src/pynwb/io/ecephys.py src/pynwb/io/epoch.py src/pynwb/io/file.py src/pynwb/io/icephys.py src/pynwb/io/image.py src/pynwb/io/misc.py src/pynwb/io/ogen.py src/pynwb/io/ophys.py src/pynwb/io/retinotopy.py src/pynwb/io/utils.py src/pynwb/legacy/__init__.py src/pynwb/legacy/map.py src/pynwb/legacy/io/__init__.py src/pynwb/legacy/io/base.py src/pynwb/legacy/io/behavior.py src/pynwb/legacy/io/ecephys.py src/pynwb/legacy/io/epoch.py src/pynwb/legacy/io/file.py src/pynwb/legacy/io/icephys.py src/pynwb/legacy/io/image.py src/pynwb/legacy/io/misc.py src/pynwb/legacy/io/ogen.py src/pynwb/legacy/io/ophys.py src/pynwb/legacy/io/retinotopy.py src/pynwb/nwb-schema/core/nwb.base.yaml src/pynwb/nwb-schema/core/nwb.behavior.yaml src/pynwb/nwb-schema/core/nwb.device.yaml src/pynwb/nwb-schema/core/nwb.ecephys.yaml src/pynwb/nwb-schema/core/nwb.epoch.yaml src/pynwb/nwb-schema/core/nwb.file.yaml src/pynwb/nwb-schema/core/nwb.icephys.yaml src/pynwb/nwb-schema/core/nwb.image.yaml src/pynwb/nwb-schema/core/nwb.misc.yaml src/pynwb/nwb-schema/core/nwb.namespace.yaml src/pynwb/nwb-schema/core/nwb.ogen.yaml src/pynwb/nwb-schema/core/nwb.ophys.yaml src/pynwb/nwb-schema/core/nwb.retinotopy.yaml src/pynwb/testing/__init__.py src/pynwb/testing/icephys_testutils.py src/pynwb/testing/make_test_files.py src/pynwb/testing/testh5io.py src/pynwb/testing/utils.py src/pynwb/testing/mock/__init__.py src/pynwb/testing/mock/base.py src/pynwb/testing/mock/behavior.py src/pynwb/testing/mock/device.py src/pynwb/testing/mock/ecephys.py src/pynwb/testing/mock/file.py src/pynwb/testing/mock/icephys.py src/pynwb/testing/mock/ogen.py src/pynwb/testing/mock/ophys.py src/pynwb/testing/mock/utils.py tests/__init__.py tests/back_compat/1.0.2_nwbfile.nwb tests/back_compat/1.0.2_str_experimenter.nwb tests/back_compat/1.0.2_str_pub.nwb tests/back_compat/1.0.3_nwbfile.nwb tests/back_compat/1.0.3_str_experimenter.nwb tests/back_compat/1.0.3_str_pub.nwb tests/back_compat/1.1.0_nwbfile.nwb tests/back_compat/1.1.0_str_experimenter.nwb tests/back_compat/1.1.0_str_pub.nwb tests/back_compat/1.1.2_nwbfile.nwb tests/back_compat/1.1.2_str_experimenter.nwb tests/back_compat/1.1.2_str_pub.nwb tests/back_compat/1.5.1_imageseries_no_data.nwb tests/back_compat/1.5.1_imageseries_no_unit.nwb tests/back_compat/1.5.1_timeseries_no_data.nwb tests/back_compat/1.5.1_timeseries_no_unit.nwb tests/back_compat/2.1.0_imageseries_no_data.nwb tests/back_compat/2.1.0_imageseries_non_external_format.nwb tests/back_compat/2.1.0_imageseries_nonmatch_starting_frame.nwb tests/back_compat/2.1.0_nwbfile_with_extension.nwb tests/back_compat/2.2.0_subject_no_age__reference.nwb tests/back_compat/__init__.py tests/back_compat/test_import_structure.py tests/back_compat/test_read.py tests/coverage/runCoverage tests/integration/__init__.py tests/integration/hdf5/__init__.py tests/integration/hdf5/test_base.py tests/integration/hdf5/test_device.py tests/integration/hdf5/test_ecephys.py tests/integration/hdf5/test_icephys.py tests/integration/hdf5/test_image.py tests/integration/hdf5/test_io.py tests/integration/hdf5/test_misc.py tests/integration/hdf5/test_modular_storage.py tests/integration/hdf5/test_nwbfile.py tests/integration/hdf5/test_ogen.py tests/integration/hdf5/test_ophys.py tests/integration/hdf5/test_retinotopy.py tests/integration/hdf5/test_scratch.py tests/integration/ros3/__init__.py tests/integration/ros3/test_ros3.py tests/integration/utils/__init__.py tests/integration/utils/test_io_utils.py tests/read_dandi/__init__.py tests/read_dandi/test_read_dandi.py tests/unit/__init__.py tests/unit/test_base.py tests/unit/test_behavior.py tests/unit/test_core.py tests/unit/test_core_NWBContainer.py tests/unit/test_device.py tests/unit/test_ecephys.py tests/unit/test_epoch.py tests/unit/test_epoch_legacy.py tests/unit/test_extension.py tests/unit/test_file.py tests/unit/test_icephys.py tests/unit/test_icephys_metadata_tables.py tests/unit/test_image.py tests/unit/test_misc.py tests/unit/test_mock.py tests/unit/test_ogen.py tests/unit/test_ophys.py tests/unit/test_resources.py tests/unit/test_retinotopy.py tests/unit/test_scratch.py tests/unit/test_spec.py tests/validation/__init__.py tests/validation/test_validate.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397558.0 pynwb-2.5.0/src/pynwb.egg-info/dependency_links.txt0000644000175100001730000000000114467767766022002 0ustar00runnerdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397403.0 pynwb-2.5.0/src/pynwb.egg-info/not-zip-safe0000644000175100001730000000000114467767533020152 0ustar00runnerdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397558.0 pynwb-2.5.0/src/pynwb.egg-info/requires.txt0000644000175100001730000000012314467767766020330 0ustar00runnerdockerh5py>=2.10 hdmf>=3.9.0 numpy>=1.16 pandas>=1.1.5 python-dateutil>=2.7.3 setuptools ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397558.0 pynwb-2.5.0/src/pynwb.egg-info/top_level.txt0000644000175100001730000000000614467767766020462 0ustar00runnerdockerpynwb ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/test.py0000755000175100001730000003566114467767506013653 0ustar00runnerdocker#!/usr/bin/env python import warnings import re import argparse import glob import inspect import logging import os.path import os from subprocess import run, PIPE, STDOUT import sys import traceback import unittest flags = { 'pynwb': 2, 'integration': 3, 'example': 4, 'backwards': 5, 'validate-examples': 6, 'ros3': 7, 'example-ros3': 8, 'validation-module': 9 } TOTAL = 0 FAILURES = 0 ERRORS = 0 class SuccessRecordingResult(unittest.TextTestResult): '''A unittest test result class that stores successful test cases as well as failures and skips. ''' def addSuccess(self, test): if not hasattr(self, 'successes'): self.successes = [test] else: self.successes.append(test) def get_all_cases_run(self): '''Return a list of each test case which failed or succeeded ''' cases = [] if hasattr(self, 'successes'): cases.extend(self.successes) cases.extend([failure[0] for failure in self.failures]) return cases def run_test_suite(directory, description="", verbose=True): global TOTAL, FAILURES, ERRORS logging.info("running %s" % description) directory = os.path.join(os.path.dirname(__file__), directory) runner = unittest.TextTestRunner(verbosity=verbose, resultclass=SuccessRecordingResult) # set top_level_dir below to prevent import name clashes between # tests/unit/test_base.py and tests/integration/hdf5/test_base.py test_result = runner.run(unittest.TestLoader().discover(directory, top_level_dir='tests')) TOTAL += test_result.testsRun FAILURES += len(test_result.failures) ERRORS += len(test_result.errors) return test_result def _import_from_file(script): import imp return imp.load_source(os.path.basename(script), script) warning_re = re.compile("Parent module '[a-zA-Z0-9]+' not found while handling absolute import") ros3_examples = [ os.path.join('general', 'read_basics.py'), os.path.join('advanced_io', 'streaming.py'), ] allensdk_examples = [ os.path.join('domain', 'brain_observatory.py'), # TODO create separate workflow for this ] def run_example_tests(): """Run the Sphinx gallery example files, excluding ROS3-dependent ones, to check for errors.""" logging.info('running example tests') examples_scripts = list() for root, dirs, files in os.walk(os.path.join(os.path.dirname(__file__), "docs", "gallery")): for f in files: if f.endswith(".py"): name_with_parent_dir = os.path.join(os.path.basename(root), f) if name_with_parent_dir in ros3_examples or name_with_parent_dir in allensdk_examples: logging.info("Skipping %s" % name_with_parent_dir) continue examples_scripts.append(os.path.join(root, f)) __run_example_tests_helper(examples_scripts) def run_example_ros3_tests(): """Run the Sphinx gallery example files that depend on ROS3 to check for errors.""" logging.info('running example ros3 tests') examples_scripts = list() for root, dirs, files in os.walk(os.path.join(os.path.dirname(__file__), "docs", "gallery")): for f in files: if f.endswith(".py"): name_with_parent_dir = os.path.join(os.path.basename(root), f) if name_with_parent_dir not in ros3_examples: logging.info("Skipping %s" % name_with_parent_dir) continue examples_scripts.append(os.path.join(root, f)) __run_example_tests_helper(examples_scripts) def __run_example_tests_helper(examples_scripts): global TOTAL, FAILURES, ERRORS TOTAL += len(examples_scripts) for script in examples_scripts: try: logging.info("Executing %s" % script) ws = list() with warnings.catch_warnings(record=True) as tmp: _import_from_file(script) for w in tmp: # ignore RunTimeWarnings about importing if isinstance(w.message, RuntimeWarning) and not warning_re.match(str(w.message)): ws.append(w) for w in ws: warnings.showwarning(w.message, w.category, w.filename, w.lineno, w.line) except Exception: print(traceback.format_exc()) FAILURES += 1 ERRORS += 1 def validate_nwbs(): global TOTAL, FAILURES, ERRORS logging.info('running validation tests on NWB files') examples_nwbs = glob.glob('*.nwb') import pynwb for nwb in examples_nwbs: try: logging.info("Validating file %s" % nwb) ws = list() with warnings.catch_warnings(record=True) as tmp: logging.info("Validating with pynwb.validate method.") with pynwb.NWBHDF5IO(nwb, mode='r') as io: errors = pynwb.validate(io) TOTAL += 1 if errors: FAILURES += 1 ERRORS += 1 for err in errors: print("Error: %s" % err) def get_namespaces(nwbfile): comp = run(["python", "-m", "pynwb.validate", "--list-namespaces", "--cached-namespace", nwb], stdout=PIPE, stderr=STDOUT, universal_newlines=True, timeout=30) if comp.returncode != 0: return [] return comp.stdout.split() namespaces = get_namespaces(nwb) if len(namespaces) == 0: FAILURES += 1 ERRORS += 1 cmds = [] cmds += [["python", "-m", "pynwb.validate", nwb]] cmds += [["python", "-m", "pynwb.validate", "--cached-namespace", nwb]] cmds += [["python", "-m", "pynwb.validate", "--no-cached-namespace", nwb]] for ns in namespaces: # for some reason, this logging command is necessary to correctly printing the namespace in the # next logging command logging.info("Namespace found: %s" % ns) cmds += [["python", "-m", "pynwb.validate", "--cached-namespace", "--ns", ns, nwb]] for cmd in cmds: logging.info("Validating with \"%s\"." % (" ".join(cmd[:-1]))) comp = run(cmd, stdout=PIPE, stderr=STDOUT, universal_newlines=True, timeout=30) TOTAL += 1 if comp.returncode != 0: FAILURES += 1 ERRORS += 1 print("Error: %s" % comp.stdout) for w in tmp: # ignore RunTimeWarnings about importing if isinstance(w.message, RuntimeWarning) and not warning_re.match(str(w.message)): ws.append(w) for w in ws: warnings.showwarning(w.message, w.category, w.filename, w.lineno, w.line) except Exception: print(traceback.format_exc()) FAILURES += 1 ERRORS += 1 def run_integration_tests(verbose=True): pynwb_test_result = run_test_suite("tests/integration/hdf5", "integration tests", verbose=verbose) test_cases = pynwb_test_result.get_all_cases_run() import pynwb type_map = pynwb.get_type_map() tested_containers = {} for test_case in test_cases: if not hasattr(test_case, 'container'): continue container_class = test_case.container.__class__ if container_class not in tested_containers: tested_containers[container_class] = [test_case._testMethodName] else: tested_containers[container_class].append(test_case._testMethodName) count_missing = 0 for container_class in type_map.get_container_classes('core'): if container_class not in tested_containers: count_missing += 1 if verbose > 1: logging.info('%s missing test case; should define in %s' % (container_class, inspect.getfile(container_class))) if count_missing > 0: logging.info('%d classes missing integration tests in ui_write' % count_missing) else: logging.info('all classes have integration tests') run_test_suite("tests/integration/utils", "integration utils tests", verbose=verbose) def clean_up_tests(): # remove files generated from running example files files_to_remove = [ "advanced_io_example.nwb", "basic_alternative_custom_write.nwb", "basic_iterwrite_example.nwb", "basic_sparse_iterwrite_*.nwb", "basic_sparse_iterwrite_*.npy", "basics_tutorial.nwb", "behavioral_tutorial.nwb", "brain_observatory.nwb", "cache_spec_example.nwb", "ecephys_tutorial.nwb", "ecog.extensions.yaml", "ecog.namespace.yaml", "ex_test_icephys_file.nwb", "example_timeintervals_file.nwb", "exported_nwbfile.nwb", "external_linkcontainer_example.nwb", "external_linkdataset_example.nwb", "external1_example.nwb", "external2_example.nwb", "icephys_example.nwb", "icephys_pandas_testfile.nwb", "images_tutorial.nwb", "manifest.json", "mylab.extensions.yaml", "mylab.namespace.yaml", "nwbfile.nwb", "ophys_tutorial.nwb", "processed_data.nwb", "raw_data.nwb", "scratch_analysis.nwb", "test_cortical_surface.nwb", "test_icephys_file.nwb", "test_multicontainerinterface.extensions.yaml", "test_multicontainerinterface.namespace.yaml", "test_multicontainerinterface.nwb", ] for f in files_to_remove: for name in glob.glob(f): if os.path.exists(name): os.remove(name) def main(): # setup and parse arguments parser = argparse.ArgumentParser('python test.py [options]') parser.set_defaults(verbosity=1, suites=[]) parser.add_argument('-v', '--verbose', const=2, dest='verbosity', action='store_const', help='run in verbose mode') parser.add_argument('-q', '--quiet', const=0, dest='verbosity', action='store_const', help='run disabling output') parser.add_argument('-p', '--pynwb', action='append_const', const=flags['pynwb'], dest='suites', help='run unit tests for pynwb package') parser.add_argument('-i', '--integration', action='append_const', const=flags['integration'], dest='suites', help='run integration tests') parser.add_argument('-e', '--example', action='append_const', const=flags['example'], dest='suites', help='run example tests') parser.add_argument('-f', '--example-ros3', action='append_const', const=flags['example-ros3'], dest='suites', help='run example tests with ros3 streaming') parser.add_argument('-b', '--backwards', action='append_const', const=flags['backwards'], dest='suites', help='run backwards compatibility tests') parser.add_argument('-w', '--validate-examples', action='append_const', const=flags['validate-examples'], dest='suites', help='run example tests and validation tests on example NWB files') parser.add_argument('-r', '--ros3', action='append_const', const=flags['ros3'], dest='suites', help='run ros3 streaming tests') parser.add_argument('-x', '--validation-module', action='append_const', const=flags['validation-module'], dest='suites', help='run tests on pynwb.validate') args = parser.parse_args() if not args.suites: args.suites = list(flags.values()) # remove from test suites run by default args.suites.pop(args.suites.index(flags['example'])) args.suites.pop(args.suites.index(flags['example-ros3'])) args.suites.pop(args.suites.index(flags['validate-examples'])) args.suites.pop(args.suites.index(flags['ros3'])) args.suites.pop(args.suites.index(flags['validation-module'])) # set up logger root = logging.getLogger() root.setLevel(logging.INFO) ch = logging.StreamHandler(sys.stdout) ch.setLevel(logging.INFO) formatter = logging.Formatter('======================================================================\n' '%(asctime)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) root.addHandler(ch) warnings.simplefilter('always') warnings.filterwarnings("ignore", category=ImportWarning, module='importlib._bootstrap', message=("can't resolve package from __spec__ or __package__, falling back on __name__ " "and __path__")) # Run unit tests for pynwb package if flags['pynwb'] in args.suites: run_test_suite("tests/unit", "pynwb unit tests", verbose=args.verbosity) # Run example tests is_run_example_tests = False if flags['example'] in args.suites or flags['validate-examples'] in args.suites: run_example_tests() is_run_example_tests = True # Run example tests with ros3 streaming examples # NOTE this requires h5py to be built with ROS3 support and the dandi package to be installed # this is most easily done by creating a conda environment using environment-ros3.yml if flags['example-ros3'] in args.suites: run_example_ros3_tests() # Run validation tests on the example NWB files generated above if flags['validate-examples'] in args.suites: validate_nwbs() # Run integration tests if flags['integration'] in args.suites: run_integration_tests(verbose=args.verbosity) # Run validation module tests, requires coverage to be installed if flags['validation-module'] in args.suites: run_test_suite("tests/validation", "validation tests", verbose=args.verbosity) # Run backwards compatibility tests if flags['backwards'] in args.suites: run_test_suite("tests/back_compat", "pynwb backwards compatibility tests", verbose=args.verbosity) # Run ros3 streaming tests if flags['ros3'] in args.suites: run_test_suite("tests/integration/ros3", "pynwb ros3 streaming tests", verbose=args.verbosity) # Delete files generated from running example tests above if is_run_example_tests: clean_up_tests() final_message = 'Ran %s tests' % TOTAL exitcode = 0 if ERRORS > 0 or FAILURES > 0: exitcode = 1 _list = list() if ERRORS > 0: _list.append('errors=%d' % ERRORS) if FAILURES > 0: _list.append('failures=%d' % FAILURES) final_message = '%s - FAILED (%s)' % (final_message, ','.join(_list)) else: final_message = '%s - OK' % final_message logging.info(final_message) return exitcode if __name__ == "__main__": sys.exit(main()) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5500274 pynwb-2.5.0/tests/0000755000175100001730000000000014467767767013457 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/__init__.py0000644000175100001730000000000014467767506015545 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5540276 pynwb-2.5.0/tests/back_compat/0000755000175100001730000000000014467767767015722 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.0.2_nwbfile.nwb0000644000175100001730000003140014467767506020563 0ustar00runnerdockerHDF  3` TREEHP/HEAP`-HhTREEHEAPXPSNOD Hh(Pp PH0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREEHEAPXP @help=1"]x GCOL 2019-11-27T17:28:27.611843-08:00ADDMEADDME 2019-11-27T17:28:27.610392-08:00 2019-11-27T17:28:27.610392-08:00=an NWB:N file for storing cellular-based neurophysiology data2.0bcore NWBFile2"]2"]2"]acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timeSNODh*(  0 x+,8  02"] H nwb_version H namespace Hneurodata_type   ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.0.2_str_experimenter.nwb0000644000175100001730000003642014467767506022543 0ustar00runnerdockerHDF  =` TREEH:HEAP`H0HhTREEHEAPXPSNOD Hh(Pp P,H0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREE*HEAPXexperimenter@ @help=<"]GCOLone experimenter 2019-11-27T17:28:27.944667-08:00ADDMEADDME 2019-11-27T17:28:27.943534-08:00 2019-11-27T17:28:27.943534-08:00=an NWB:N file for storing cellular-based neurophysiology data2.0b core NWBFilexSNOD2"]x2"]2"]2"]acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_time3"]   SNODh-(  0 x(.8/8  1 H nwb_version H namespace Hneurodata_type ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.0.2_str_pub.nwb0000644000175100001730000003642014467767506020622 0ustar00runnerdockerHDF  =` TREEH:HEAP`H0HhTREEHEAPXPSNOD Hh(Pp P,H0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREE*HEAPX related_publications8 @help=<"]GCOLone publication 2019-11-27T17:28:28.258339-08:00ADDMEADDME 2019-11-27T17:28:28.257615-08:00 2019-11-27T17:28:28.257615-08:00=an NWB:N file for storing cellular-based neurophysiology data2.0b core NWBFilexSNOD2"]x2"]2"]2"]acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_time3"]   SNODh-(  0 x(.8/8  1 H nwb_version H namespace Hneurodata_type ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.0.3_nwbfile.nwb0000644000175100001730000043022014467767506020567 0ustar00runnerdockerHDF  0` TREEHP/HEAP`- 0 .speclocpHhTREEHEAPXPSNOD Hh(Pp PH0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREEHEAPXP @help=1:<#]x GCOL 2019-11-27T17:32:04.543292-08:00ADDMEADDME 2019-11-27T17:32:04.542259-08:00 2019-11-27T17:32:04.542259-08:00=an NWB:N file for storing cellular-based neurophysiology data2.0.2core NWBFile  {"groups":[{"datasets":[{"dtype":"float","name":"start_time","doc":"Start time of epoch, in seconds","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'start time of the epoch, in seconds'","dtype":"text","value":"start time of the epoch, in seconds"}]},{"dtype":"float","name":"stop_time","doc":"Stop time of epoch, in seconds","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'stop time of the epoch, in seconds'","dtype":"text","value":"stop time of the epoch, in seconds"}]},{"dtype":"text","name":"tags","doc":"User-defined tags that identify events. Tags are to help identify or categorize events.","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'user-defined tags'","dtype":"text","value":"user-defined tags"}]},{"name":"tags_index","doc":"Index for tags","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries data[] field. COMMENT: This can be used to calculate location in TimeSeries timestamp[] field","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"name":"timeseries","doc":"An index into a TimeSeries object","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"name":"help","doc":"Value is 'Data on how an epoch applies to a time series'","dtype":"text","value":"Data on how an epoch applies to a time series"}]},{"name":"timeseries_index","doc":"Index for timeseries","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals","attributes":[{"name":"help","doc":"Value is 'A general epoch object'","dtype":"text","value":"A general epoch object"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}2#]2#]2#]acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh*(  0 x+,p:<8  02#] H nwb_version H namespace Hneurodata_type P  *xF  &xBx-xx5S#8SS x]1SSUSTREE@HEAPX=coreH=?TREE DHEAPX?2.0.2HSNODX==?ACTREEp OHEAP`HwSNOD`AAC3#]GCOL8**{"datasets":[{"doc":"An abstract data type for a dataset","neurodata_type_def":"NWBData","attributes":[{"name":"help","doc":"Short description of what this type of Interface contains.","dtype":"text"}]},{"doc":"Pointers that index data values","neurodata_type_inc":"NWBData","neurodata_type_def":"Index","attributes":[{"name":"help","doc":"a help string","dtype":"text","value":"indexes into a list of values for a list of elements"},{"name":"target","doc":"the target dataset that this index applies to","dtype":{"target_type":"NWBData","reftype":"object"}}]},{"doc":"Data values indexed by pointer","neurodata_type_inc":"NWBData","neurodata_type_def":"VectorData","attributes":[{"name":"help","doc":"a help string","dtype":"text","value":"Values for a list of elements"},{"name":"description","doc":"A short description of what these vectors are","dtype":"text"}]},{"doc":"Pointers that index data values","neurodata_type_inc":"Index","neurodata_type_def":"VectorIndex","attributes":[{"name":"target","doc":"the target dataset that this index applies to","dtype":{"target_type":"VectorData","reftype":"object"}},{"name":"help","doc":"a help string","dtype":"text","value":"indexes into a list of values for a list of elements"}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"a unique identifier for each element","default_name":"element_id","neurodata_type_inc":"NWBData","neurodata_type_def":"ElementIdentifiers","attributes":[{"name":"help","doc":"a help string","dtype":"text","value":"unique identifiers for a list of elements"}]},{"dtype":"int","doc":"a region/index into a DynamicTable","neurodata_type_inc":"VectorData","neurodata_type_def":"DynamicTableRegion","attributes":[{"name":"help","doc":"value is 'a subset (i.e. slice or region) of a DynamicTable'","dtype":"text","value":"a subset (i.e. slice or region) of a DynamicTable"},{"name":"table","doc":"a reference to the DynamicTable this region applies to","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"name":"description","doc":"Description of what this table region points to","dtype":"text"}]},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["num_x","num_y"],["num_x","num_y","(r, g, b)"],["num_x","num_y","(r, g, b, a)"]],"doc":"Image base type.","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_def":"NWBContainer","attributes":[{"name":"help","doc":"Short description of what this type of NWBContainer contains.","dtype":"text"}]},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface","attributes":[{"name":"help","doc":"Short description of what this type of NWBContainer contains.","dtype":"text"}]},{"groups":[{"name":"sync","doc":"Lab specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. COMMENT: This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","quantity":"?"}],"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"uint8","name":"control","doc":"Numerical labels that apply to each element in data[]. COMMENT: Optional field. If present, the control array should have the same number of elements as data[].","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","name":"control_description","doc":"Description of each control value. COMMENT: Array length should be as long as the highest number in control minus one, generating an zero-based indexed array for control values.","quantity":"?"},{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"name":"data","doc":"Data values. Can also store binary data (eg, image frames) COMMENT: This field may be a link to data stored in an external file, especially in the case of raw data.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"dtype":"float64","name":"starting_time","doc":"The timestamp of the first sample. COMMENT: When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate.","quantity":"?","attributes":[{"name":"rate","doc":"Sampling rate, in Hz COMMENT: Rate information is stored in Hz","dtype":"float32"},{"name":"unit","doc":"Value is 'Seconds'","dtype":"text","value":"Seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data.COMMENT: Timestamps here have all been corrected to the common experiment master-clock. Time is stored as seconds and all timestamps are relative to experiment start time.","quantity":"?","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Value is 'Seconds'","dtype":"text","value":"Seconds"}]}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"},{"name":"help","doc":"Value is 'General time series object'","dtype":"text","value":"General time series object"}]},{"groups":[{"doc":"Interface objects containing data output from processing steps","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"doc":"Module. Name should be descriptive. Stores a collection of related data organized by contained interfaces. Each interface is a contract specifying content related to a particular type of data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"name":"description","doc":"Description of Module","dtype":"text"},{"name":"help","doc":"Value is 'A collection of analysis outputs from processing of data'","dtype":"text","value":"A collection of analysis outputs from processing of data"}]},{"datasets":[{"doc":"Images stored in this NWBDataInterface","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A NWBDataInterface for storing images that have some relationship","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"name":"description","doc":"Description of images in this container","dtype":"text"},{"name":"help","doc":"Value is 'A collection of images that have some meaningful relationship'","dtype":"text","value":"A collection of images that have some meaningful relationship"}]},{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"The unique identifier for the rows in this dynamic table","neurodata_type_inc":"ElementIdentifiers"},{"doc":"The vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"The indices for the vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorIndex"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). Apart from a column that contains unique identifiers for each row there are no other required datasets. Users are free to add any number of VectorData objects here. Table functionality is already supported through compound types, which is analogous to storing an array-of-structs. DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable. For example, DynamicTable was originally developed for storing trial data and spike unit metadata. Both of these use cases are expected to produce relatively small tables, so the spatial locality of multiple datasets present in a DynamicTable is not expected to have a significant performance impact. Additionally, requirements of trial and unit metadata tables are sufficiently diverse that performance implications can be overlooked in favor of usability.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DynamicTable","attributes":[{"name":"help","doc":"Value is 'A column-centric table'","dtype":"text","value":"A column-centric table"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}SNODRhEX8vhKq3#] 3#]03#]@3#]P3#]nwb.basenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOL@&{"datasets":[{"shape":[null,null],"dims":["y","x"],"doc":"Grayscale image","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]},{"shape":[null,null,3],"dims":["y","x","R,G,B"],"doc":"Color image","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]},{"shape":[null,null,4],"dims":["y","x","R,G,B,A"],"doc":"Color image with transparency","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","y","x"],["frame","z","y","x"]],"dtype":"numeric","name":"data","doc":"Either binary data containing image or empty.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","name":"dimension","doc":"Number of pixels on x, y, (and z) axes.","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","name":"external_file","doc":"Path or URL to one or more external file(s). Field only present if format=external. NOTE: this is only relevant if the image is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another HDF5 file and that file is HDF5 linked to this file.","quantity":"?","attributes":[{"name":"starting_frame","doc":"Each entry is the frame number (within the full ImageSeries) of the first frame in the corresponding external_file entry. This serves as an index to what frames each file contains, allowing random access.Zero-based indexing is used. (The first element will always be zero).","dtype":"int","shape":[null],"dims":["num_files"]}]},{"dtype":"text","name":"format","doc":"Format of image. If this is 'external' then the field external_file contains the path or URL information to that file. For tiff, png, jpg, etc, the binary representation of the image is stored in data. If the format is raw then the fields bit_per_pixel and dimension are used. For raw images, only a single channel is stored (eg, red).","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the HDF5 file in a raw format while other times it will be stored as an external image file in the host file system. The data field will either be binary data or empty. TimeSeries::data array structure: [frame] [y][x] or [frame][z][y][x].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries","attributes":[{"name":"help","doc":"Value is 'Storage object for time-series 2-D image data'","dtype":"text","value":"Storage object for time-series 2-D image data"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"links":[{"name":"masked_imageseries","doc":"Link to ImageSeries that mask is applied to.","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The data[] array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries","attributes":[{"name":"help","doc":"Value is 'An alpha mask that is applied to a presented visual stimulus'","dtype":"text","value":"An alpha mask that is applied to a presented visual stimulus"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"float32","name":"distance","doc":"Distance from camera/monitor to target/eye.","quantity":"?"},{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area (meters).","quantity":"?"},{"dtype":"text","name":"orientation","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (eg, how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries","attributes":[{"name":"help","doc":"Value is 'Time-series image stack for optical recording or stimulus'","dtype":"text","value":"Time-series image stack for optical recording or stimulus"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int","name":"data","doc":"Index of the frame in the referenced ImageSeries.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]}],"links":[{"name":"indexed_timeseries","doc":"HDF5 link to TimeSeries containing images that are indexed.","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries","attributes":[{"name":"help","doc":"Value is 'A sequence that is generated from an existing image stack. Frames can be presented in an arbitrary order. The data[] field stores frame number in reference stack'","dtype":"text","value":"A sequence that is generated from an existing image stack. Frames can be presented in an arbitrary order. The data[] field stores frame number in reference stack"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]}]}B{"groups":[{"groups":[{"groups":[{"doc":"Any objects representing acquired data","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"name":"acquisition","doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. COMMENT: This group is read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external HDF5 files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. MORE_INFO: Acquired data includes tracking and experimental data streams (ie, everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate HDF5 file that is linked to by the file being used for processing and analysis."},{"groups":[{"doc":"Custom analysis results","quantity":"*","neurodata_type_inc":"NWBContainer"}],"name":"analysis","doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. COMMENT: To facilitate sharing analysis data between labs, the contents here should be stored in standard types (eg, INCF types) and appropriately documented. MORE_INFO: The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs."},{"groups":[{"doc":"Intermediate analysis of acquired data","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"name":"processing","doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. COMMENT: Modules are defined below. They can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. MORE_INFO: 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis. These are performed using Modules, as defined above. All modules reside in the processing group."},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"presentation","doc":"Stimuli presented during the experiment."},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"templates","doc":"Template stimuli. COMMENT: Time stamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame."}],"name":"stimulus","doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus) COMMENT: This group is read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. MORE_INFO: Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be HDF5-linked to a remote library file."},{"groups":[{"doc":"place-holder than can be extended so that lab-specific meta-data can be placed in /general","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData","attributes":[{"name":"help","doc":"Short description of what this type of NWBContainer contains.","dtype":"text"}]},{"groups":[{"doc":"One of possibly many. Information about device and device description.","quantity":"+","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"name":"help","doc":"Value is 'A recording device e.g. amplifier'.","dtype":"text","value":"A recording device e.g. amplifier"}]}],"name":"devices","doc":"Description of hardware devices used during experiment. COMMENT: Eg, monitors, ADC boards, microscopes, etc","quantity":"?"},{"datasets":[{"dtype":"text","name":"age","doc":"Age of subject","quantity":"?"},{"dtype":"isodatetime","name":"date_of_birth","doc":"can be supplied instead of age","quantity":"?"},{"dtype":"text","name":"description","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","quantity":"?"},{"dtype":"text","name":"genotype","doc":"Genetic strain COMMENT: If absent, assume Wild Type (WT)","quantity":"?"},{"dtype":"text","name":"sex","doc":"Gender of subject","quantity":"?"},{"dtype":"text","name":"species","doc":"Species of subject","quantity":"?"},{"dtype":"text","name":"subject_id","doc":"ID of animal/person used/participating in experiment (lab convention)","quantity":"?"},{"dtype":"text","name":"weight","doc":"Weight at time of experiment, at time of surgery and at other important times","quantity":"?"}],"name":"subject","doc":"Information about the animal or person from which the data was measured.","quantity":"?","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject","attributes":[{"name":"help","doc":"Value is 'Information about the subject'","dtype":"text","value":"Information about the subject"}]},{"groups":[{"doc":"One of possibly many groups, one for each electrode group.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float","name":"x","doc":"the x coordinate of the channel location","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the x coordinate of the channel location'","dtype":"text","value":"the x coordinate of the channel location"}]},{"dtype":"float","name":"y","doc":"the y coordinate of the channel location","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the y coordinate of the channel location'","dtype":"text","value":"the y coordinate of the channel location"}]},{"dtype":"float","name":"z","doc":"the z coordinate of the channel location","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the z coordinate of the channel location'","dtype":"text","value":"the z coordinate of the channel location"}]},{"dtype":"float","name":"imp","doc":"the impedance of the channel","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the impedance of the channel'","dtype":"text","value":"the impedance of the channel"}]},{"dtype":"ascii","name":"location","doc":"the location of channel within the subject e.g. brain region","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the location of channel within the subject e.g. brain region'","dtype":"text","value":"the location of channel within the subject e.g. brain region"}]},{"dtype":"float","name":"filtering","doc":"description of hardware filtering","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'description of hardware filtering'","dtype":"text","value":"description of hardware filtering"}]},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"group","doc":"a reference to the ElectrodeGroup this electrode is a part of","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'a reference to the ElectrodeGroup this electrode is a part of'","dtype":"text","value":"a reference to the ElectrodeGroup this electrode is a part of"}]},{"dtype":"ascii","name":"group_name","doc":"name of the ElectrodeGroup this electrode is a part of","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the name of the ElectrodeGroup this electrode is a part of'","dtype":"text","value":"the name of the ElectrodeGroup this electrode is a part of"}]}],"name":"electrodes","doc":"A table of all electrodes (i.e. channels) used for recording.","quantity":"?","neurodata_type_inc":"DynamicTable"}],"name":"extracellular_ephys","doc":"Metadata related to extracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"One of possibly many. COMMENT: Name should be informative.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"name":"sweep_table","doc":"The table which groups different PatchClampSeries together.","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","name":"filtering","doc":"Description of filtering used. COMMENT: Includes filtering type and parameters, frequency fall- off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","quantity":"?"}],"name":"intracellular_ephys","doc":"Metadata related to intracellular electrophysiology","quantity":"?"},{"groups":[{"doc":"One of possibly many groups describing an optogenetic stimulation site. COMMENT: Name is arbitrary but should be meaningful. Name is referenced by OptogeneticSeries.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"name":"optogenetics","doc":"Metadata describing optogenetic stimuluation","quantity":"?"},{"groups":[{"doc":"One of possibly many groups describing an imaging plane. COMMENT: Name is arbitrary but should be meaningful. It is referenced by TwoPhotonSeries and also ImageSegmentation and DfOverF interfaces.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"name":"optophysiology","doc":"Metadata related to optophysiology.","quantity":"?"}],"datasets":[{"dtype":"text","name":"data_collection","doc":"Notes about data collection and analysis.COMMENT: Can be from Methods","quantity":"?"},{"dtype":"text","name":"experiment_description","doc":"General description of the experiment.COMMENT: Can be from Methods","quantity":"?"},{"dtype":"text","name":"experimenter","doc":"Name of person who performed the experiment.COMMENT: More than one person OK. Can specify roles of different people involved.","quantity":"?"},{"dtype":"text","name":"institution","doc":"Institution(s) where experiment was performed","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","name":"keywords","doc":"Terms to search over","quantity":"?"},{"dtype":"text","name":"lab","doc":"Lab where experiment was performed","quantity":"?"},{"dtype":"text","name":"notes","doc":"Notes about the experiment. COMMENT: Things particular to this experiment","quantity":"?"},{"dtype":"text","name":"pharmacology","doc":"Description of drugs used, including how and when they were administered. COMMENT: Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","quantity":"?"},{"dtype":"text","name":"protocol","doc":"Experimental protocol, if applicable. COMMENT: E.g., include IACUC protocol.","quantity":"?"},{"dtype":"text","name":"related_publications","doc":"Publication information. COMMENT: PMID, DOI, URL, etc. If multiple, concatenate together and describe which is which. such as PMID, DOI, URL, etc","quantity":"?"},{"dtype":"text","name":"session_id","doc":"Lab-specific ID for the session.COMMENT: Only 1 session_id per file, with all time aligned to experiment start time.","quantity":"?"},{"dtype":"text","name":"slices","doc":"Description of slices, including information about preparation thickness, orientation, temperature and bath solution","quantity":"?"},{"dtype":"text","name":"source_script","doc":"Script file used to create this NWB file.","quantity":"?","attributes":[{"name":"file_name","doc":"Name of script file","dtype":"text"}]},{"dtype":"text","name":"stimulus","doc":"Notes about stimuli, such as how and where presented. COMMENT: Can be from Methods.","quantity":"?"},{"dtype":"text","name":"surgery","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery. COMMENT: Much can be copied from Methods.","quantity":"?"},{"dtype":"text","name":"virus","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","quantity":"?"}],"name":"general","doc":"Experimental metadata, including protocol, notes and description of hardware device(s). COMMENT: The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. MORE_INFO: General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them."},{"groups":[{"name":"epochs","doc":"divisions in time marking experimental stages or sub-divisions of a single recording session","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"trials","doc":"repeated experimental events that have a logical grouping","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"invalid_times","doc":"time intervals that should be removed from analysis","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"an optional additional table for describing other experimental time intervals","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"name":"intervals","doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","quantity":"?"},{"name":"units","doc":"Data about units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","name":"file_create_date","doc":"A record of the date the file was created and of subsequent modifications. COMMENT: - The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00 - Dates stored in UTC end in \"Z\" with no timezone offset. - Date accuracy is up to milliseconds. - The file can be created after the experiment was run, so this may differ from the experiment start time. - Each modification to the nwb file adds a new entry to the array."},{"dtype":"text","name":"identifier","doc":"A unique text identifier for the file. COMMENT: Eg, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files."},{"dtype":"text","name":"session_description","doc":"One or two sentences describing the experiment and data in the file."},{"dtype":"isodatetime","name":"session_start_time","doc":"Date and time of the experiment/session start. COMMENT: - The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00 - Dates stored in UTC end in \"Z\" with no timezone offset. - Date accuracy is up to milliseconds."},{"dtype":"isodatetime","name":"timestamps_reference_time","doc":"Date and time corresponding to time zero of all timestamps. COMMENT: - The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00 - Dates stored in UTC end in \"Z\" with no timezone offset. - Date accuracy is up to milliseconds. - All times stored in the file use this time as reference (ie, time zero)."}],"name":"root","doc":"Top level of NWB file.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"name":"help","doc":"Value is 'an NWB:N file for storing cellular-based neurophysiology data'","dtype":"text","value":"an NWB:N file for storing cellular-based neurophysiology data"},{"name":"nwb_version","doc":"File version string. COMMENT: Eg, NWB-1.0.0. This will be the name of the format with trailing major, minor and patch numbers.","dtype":"text","value":"2.0.2"}]}]}-{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"Values of each feature at each time.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"feature_units","doc":"Units of each feature.","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"features","doc":"Description of the features represented in TimeSeries::data."}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries","attributes":[{"name":"help","doc":"Value is 'Features of an applied stimulus. This is useful when storing the raw stimulus is impractical'","dtype":"text","value":"Features of an applied stimulus. This is useful when storing the raw stimulus is impractical"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","name":"data","doc":"Annotations made during an experiment.","attributes":[{"name":"resolution","doc":"Value is -1.0","dtype":"float","value":-1.0},{"name":"unit","doc":"Value is 'n/a'","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores, eg, user annotations made during an experiment. The TimeSeries::data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries","attributes":[{"name":"help","doc":"Value is 'Time-stamped annotations about an experiment'","dtype":"text","value":"Time-stamped annotations about an experiment"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","name":"data","doc":">0 if interval started, <0 if interval ended.","attributes":[{"name":"resolution","doc":"Value is -1.0","dtype":"float","value":-1.0},{"name":"unit","doc":"Value is 'n/a'","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries","attributes":[{"name":"help","doc":"Value is 'Stores the start and stop times for events'","dtype":"text","value":"Stores the start and stop times for events"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"groups":[{"datasets":[{"dtype":"text","name":"band_name","doc":"the name of the band e.g. theta","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the name of the band e.g. theta'","dtype":"text","value":"the name of the band e.g. theta"}]},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float","name":"band_limits","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center'","dtype":"text","value":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center"}]},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_mean","doc":"The mean Gaussian filters in Hz","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"The mean Gaussian filters in Hz","dtype":"text","value":"The mean Gaussian filters in Hz"}]},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_stdev","doc":"The standard devaition of Gaussian filters in Hz","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"The standard devaition of Gaussian filters in Hz","dtype":"text","value":"The standard devaition of Gaussian filters in Hz"}]}],"name":"bands","doc":"A table for describing the bands that this series was generated from. There should be one row in this table for each band","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","name":"data","doc":"The data goes here","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"dtype":"text","name":"metric","doc":"recommended: phase, amplitude, power"}],"links":[{"name":"source_timeseries","doc":"HDF5 link to TimesSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here","target_type":"TimeSeries","quantity":"?"}],"doc":"Holds spectral analysis of a timeseries. For instance of LFP or a speech signal","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries","attributes":[{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"},{"name":"help","doc":"Value is 'General time series object'","dtype":"text","value":"General time series object"}]},{"datasets":[{"name":"spike_times_index","doc":"the index into the spike_times dataset","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"double","name":"spike_times","doc":"the spike times for each unit","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"obs_intervals_index","doc":"the index into the obs_intervals dataset","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"double","name":"obs_intervals","doc":"the observation intervals for each unit","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"electrodes_index","doc":"the index into electrodes","quantity":"?","neurodata_type_inc":"VectorIndex"},{"name":"electrodes","doc":"the electrode that each spike unit came from","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"electrode_group","doc":"the electrode group that each spike unit came from","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_mean","doc":"the spike waveform mean for each spike unit","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_sd","doc":"the spike waveform standard deviation for each spike unit","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units","attributes":[{"name":"help","doc":"Value is 'Data about spiking units'","dtype":"text","value":"Data about spiking units"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"2-D array storing position or direction relative to some reference frame.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"meter"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"dtype":"text","name":"reference_frame","doc":"Description defining what exactly 'straight-ahead' means.","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries","attributes":[{"name":"help","doc":"Value is: Stores points in space over time. The data[] array structure is [num samples][num spatial dimensions]","dtype":"text","value":"Stores points in space over time. The data[] array structure is [num samples][num spatial dimensions]"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs","attributes":[{"name":"help","doc":"Value is 'General container for storing behavioral epochs'","dtype":"text","value":"General container for storing behavioral epochs"}]},{"groups":[{"doc":"TimeSeries object containing irregular behavioral events","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents","attributes":[{"name":"help","doc":"Value is 'Position data, whether along the x, xy or xyz axis'","dtype":"text","value":"Position data, whether along the x, xy or xyz axis"}]},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data.See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries","attributes":[{"name":"help","doc":"Value is 'General container for storing continuously sampled behavioral data.'","dtype":"text","value":"General container for storing continuously sampled behavioral data."}]},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking","attributes":[{"name":"help","doc":"Value is 'Eye-tracking data, representing pupil size'","dtype":"text","value":"Eye-tracking data, representing pupil size"}]},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking","attributes":[{"name":"help","doc":"Value is 'Eye-tracking data, representing direction of gaze'","dtype":"text","value":"Eye-tracking data, representing direction of gaze"}]},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection","attributes":[{"name":"help","doc":"Value is 'Direction as measured radially. Spatial series reference frame should indicate which direction corresponds to zero and what is the direction of positive rotation'","dtype":"text","value":"Direction as measured radially. Spatial series reference frame should indicate which direction corresponds to zero and what is the direction of positive rotation"}]},{"groups":[{"doc":"SpatialSeries object containing position data","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position","attributes":[{"name":"help","doc":"Value is 'Position data, whether along the x, xy or xyz axis'","dtype":"text","value":"Position data, whether along the x, xy or xyz axis"}]}]}S {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Applied power for optogenetic stimulus.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"watt"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]}],"links":[{"name":"site","doc":"link to OptogeneticStimulusSite group that describes the site to which this stimulus was applied","target_type":"OptogeneticStimulusSite"}],"doc":"Optogenetic stimulus. The data[] field is in unit of watts.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries","attributes":[{"name":"help","doc":"Value is 'Optogenetic stimulus'","dtype":"text","value":"Optogenetic stimulus"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of site"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength in nm"},{"dtype":"text","name":"location","doc":"Location of stimulation site"}],"links":[{"name":"device","doc":"Device that generated the stimulus","target_type":"Device"}],"doc":"One of possibly many groups describing an optogenetic stimulation site. COMMENT: Name is arbitrary but should be meaningful. Name is referenced by OptogeneticSeries","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite","attributes":[{"name":"help","doc":"Value is 'Metadata about an optogenetic stimulus site'","dtype":"text","value":"Metadata about an optogenetic stimulus site"}]}]}`3#]p3#]3#]SNOD8txM(sH(uNhPxQ3#]3#]3#]GCOL5{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Recorded voltage data.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"volt"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"name":"electrodes","doc":"the electrodes that this series was generated from","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Stores acquired voltage data from extracellular recordings. The data field of an ElectricalSeries is an int or float array storing data in Volts. TimeSeries::data array structure: :blue:`[num times] [num channels] (or [num_times] for single electrode).`","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"name":"help","doc":"Value is 'Stores acquired voltage data from extracellular recordings'","dtype":"text","value":"Stores acquired voltage data from extracellular recordings"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Spike waveforms.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"volt"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data.COMMENT: Timestamps here have all been corrected to the common experiment master-clock. Time is stored as seconds and all timestamps are relative to experiment start time. This is added here so that the timestamps is required for SpikeEventTimes.","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Value is 'Seconds'","dtype":"text","value":"Seconds"}]}],"doc":"Stores 'snapshots' of spike events (i.e., threshold crossings) in data. This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describing how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries","attributes":[{"name":"help","doc":"Value is 'Snapshots of spike events from data.'","dtype":"text","value":"Snapshots of spike events from data."},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"text","name":"waveform_filtering","doc":"Filtering applied to data before generating mean/sd"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_mean","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_sd","doc":"Stdev of waveforms for each cluster, using the same indices as in mean"}],"links":[{"name":"clustering_interface","doc":"HDF5 link to Clustering interface that was the source of the clustered data","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms","attributes":[{"name":"help","doc":"Value is 'Mean waveform shape of clusters. Waveforms should be high-pass filtered (ie, not the same bandpass filter used waveform analysis and clustering)'","dtype":"text","value":"DEPRECATED Mean waveform shape of clusters. Waveforms should be high-pass filtered (ie, not the same bandpass filter used waveform analysis and clustering)"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)"},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"num","doc":"Cluster number of each event"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","name":"peak_over_rms","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric)."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module."}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering","attributes":[{"name":"help","doc":"Value is 'Clustered spike data, whether from automatic clustering tools (eg, klustakwik) or as a result of manual sorting'","dtype":"text","value":"DEPRECATED Clustered spike data, whether from automatic clustering tools (eg, klustakwik) or as a result of manual sorting"}]},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","name":"description","doc":"Description of features (eg, ''PC1'') for each of the extracted features."},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","name":"features","doc":"Multi-dimensional array of features extracted from each event."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of events that features correspond to (can be a link)."},{"name":"electrodes","doc":"the electrodes that this series was generated from","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEvent TimeSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction","attributes":[{"name":"help","doc":"Value is 'Container for salient features of detected events'","dtype":"text","value":"Container for salient features of detected events"}]},{"datasets":[{"dtype":"text","name":"detection_method","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values."},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"source_idx","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. Module description should define what is meant by time of event (e.g., .25msec before action potential peak, zero-crossing time, etc). The index points to each event from the raw data"},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Timestamps of events, in Seconds","attributes":[{"name":"unit","doc":"The string ''Seconds''","required":false,"dtype":"text","default_value":"Seconds"}]}],"links":[{"name":"source_electricalseries","doc":"HDF5 link to ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to mandate that information be stored here","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection","attributes":[{"name":"help","doc":"Value is 'Detected spike events from voltage trace(s)'","dtype":"text","value":"Detected spike events from voltage trace(s)"}]},{"groups":[{"doc":"SpikeEventSeries object containing detected spike event waveforms","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform","attributes":[{"name":"help","doc":"Value is 'Waveform of detected extracellularly recorded spike events'","dtype":"text","value":"Waveform of detected extracellularly recorded spike events"}]},{"groups":[{"doc":"ElectricalSeries object containing filtered electrophysiology data","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Ephys data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys","attributes":[{"name":"help","doc":"Value is 'Ephys data from one or more channels that is subjected to filtering, such as for gamma or theta oscillations (LFP has its own interface). Filter properties should be noted in the ElectricalSeries'","dtype":"text","value":"Ephys data from one or more channels that is subjected to filtering, such as for gamma or theta oscillations (LFP has its own interface). Filter properties should be noted in the ElectricalSeries"}]},{"groups":[{"doc":"ElectricalSeries object containing LFP data for one or more channels","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries description or comments field.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP","attributes":[{"name":"help","doc":"Value is 'LFP data from one or more channels. Filter properties should be noted in the ElectricalSeries'","dtype":"text","value":"LFP data from one or more channels. Filter properties should be noted in the ElectricalSeries"}]},{"links":[{"name":"device","doc":"the device that was used to record from this electrode group","target_type":"Device","quantity":"?"}],"doc":"One of possibly many groups, one for each electrode group.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"name":"help","doc":"Value is 'Metadata about a physical grouping of channels'","dtype":"text","value":"A physical grouping of channels"},{"name":"description","doc":"description of this electrode group","dtype":"text"},{"name":"location","doc":"description of location of this electrode group","dtype":"text"}]}]}#8{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Recorded voltage or current.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"dtype":"float","name":"gain","doc":"Units: Volt/Amp (v-clamp) or Volt/Volt (c-clamp)","quantity":"?"}],"links":[{"name":"electrode","doc":"link to IntracellularElectrode group that describes th electrode that was used to apply or record this data","target_type":"IntracellularElectrode"}],"doc":"Stores stimulus or response current or voltage. Superclass definition for patch-clamp data (this class should not be instantiated directly).","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"name":"help","doc":"Value is 'Superclass definition for patch-clamp data'","dtype":"text","value":"Superclass definition for patch-clamp data"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"float32","name":"bias_current","doc":"Unit: Amp","quantity":"?"},{"dtype":"float32","name":"bridge_balance","doc":"Unit: Ohm","quantity":"?"},{"dtype":"float32","name":"capacitance_compensation","doc":"Unit: Farad","quantity":"?"}],"doc":"Stores voltage data recorded from intracellular current-clamp recordings. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries","attributes":[{"name":"help","doc":"Value is 'Voltage recorded from cell during current-clamp recording'","dtype":"text","value":"Voltage recorded from cell during current-clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"doc":"Stores recorded voltage data from intracellular recordings when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"name":"help","doc":"Value is 'Voltage from intracellular recordings when all current and amplifier settings are off'","dtype":"text","value":"Voltage from intracellular recordings when all current and amplifier settings are off"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"doc":"Aliases to standard PatchClampSeries. Its functionality is to better tag PatchClampSeries for machine (and human) readability of the file.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries","attributes":[{"name":"help","doc":"Value is 'Stimulus current applied during current clamp recording'","dtype":"text","value":"Stimulus current applied during current clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"float32","name":"capacitance_fast","doc":"Unit: Farad","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Farad"}]},{"dtype":"float32","name":"capacitance_slow","doc":"Unit: Farad","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Farad"}]},{"dtype":"float32","name":"resistance_comp_bandwidth","doc":"Unit: Hz","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Hz"}]},{"dtype":"float32","name":"resistance_comp_correction","doc":"Unit: %","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"percent"}]},{"dtype":"float32","name":"resistance_comp_prediction","doc":"Unit: %","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"percent"}]},{"dtype":"float32","name":"whole_cell_capacitance_comp","doc":"Unit: Farad","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Farad"}]},{"dtype":"float32","name":"whole_cell_series_resistance_comp","doc":"Unit: Ohm","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Ohm"}]}],"doc":"Stores current data recorded from intracellular voltage-clamp recordings. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries","attributes":[{"name":"help","doc":"Value is 'Current recorded from cell during voltage-clamp recording'","dtype":"text","value":"Current recorded from cell during voltage-clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"doc":"Aliases to standard PatchClampSeries. Its functionality is to better tag PatchClampSeries for machine (and human) readability of the file.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries","attributes":[{"name":"help","doc":"Value is 'Stimulus voltage applied during voltage clamp recording'","dtype":"text","value":"Stimulus voltage applied during voltage clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Recording description, description of electrode (e.g., whole-cell, sharp, etc)COMMENT: Free-form text (can be from Methods)"},{"dtype":"text","name":"filtering","doc":"Electrode specific filtering.","quantity":"?"},{"dtype":"text","name":"initial_access_resistance","doc":"Initial access resistance","quantity":"?"},{"dtype":"text","name":"location","doc":"Area, layer, comments on estimation, stereotaxis coordinates (if in vivo, etc)","quantity":"?"},{"dtype":"text","name":"resistance","doc":"Electrode resistance COMMENT: unit: Ohm","quantity":"?"},{"dtype":"text","name":"seal","doc":"Information about seal used for recording","quantity":"?"},{"dtype":"text","name":"slice","doc":"Information about slice used for recording","quantity":"?"}],"links":[{"name":"device","doc":"the device that was used to record from this electrode","target_type":"Device"}],"doc":"One of possibly many. COMMENT: Name should be informative.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode","attributes":[{"name":"help","doc":"Value is 'Metadata about an intracellular electrode'","dtype":"text","value":"Metadata about an intracellular electrode"}]},{"datasets":[{"dtype":"uint64","name":"sweep_number","doc":"The sweep number of the PatchClampSeries in that row.","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'The sweep number of the PatchClampSeries in that row'","dtype":"text","value":"The sweep number of the PatchClampSeries in that row"}]},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"name":"series","doc":"The PatchClampSeries with the sweep number in that row","neurodata_type_inc":"VectorData","attributes":[{"name":"help","doc":"Value is 'The PatchClampSeries with the sweep number in that row'","dtype":"text","value":"The PatchClampSeries with the sweep number in that row"}]},{"name":"series_index","doc":"Index for series","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable","attributes":[{"name":"help","doc":"Value is 'The table which groups different PatchClampSeries together'","dtype":"text","value":"The table which groups different PatchClampSeries together"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}]1{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":["width|height","width|height|depth"],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area (meters).","quantity":"?"}],"links":[{"name":"imaging_plane","doc":"link to ImagingPlane group from which this TimeSeries data was generated","target_type":"ImagingPlane"}],"doc":"A special case of optical imaging.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"name":"help","doc":"Value is 'Image stack recorded from 2-photon microscope'","dtype":"text","value":"Image stack recorded from 2-photon microscope"},{"name":"pmt_gain","doc":"Photomultiplier gain","required":false,"dtype":"float32"},{"name":"scan_line_rate","doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","required":false,"dtype":"float32"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","name":"data","doc":"Signals from ROIs","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"name":"rois","doc":"a dataset referencing into an ROITable containing information on the ROIs stored in this timeseries","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. Each row in data[] should correspond to the signal from one ROI.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries","attributes":[{"name":"help","doc":"Value is 'ROI responses over an imaging plane. Each element on the second dimension of data[] should correspond to the signal from one ROI'","dtype":"text","value":"ROI responses over an imaging plane. Each element on the second dimension of data[] should correspond to the signal from one ROI"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"groups":[{"doc":"RoiResponseSeries object containing dF/F for a ROI","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF","attributes":[{"name":"help","doc":"Value is 'Df/f over time of one or more ROIs. TimeSeries names should correspond to imaging plane names'","dtype":"text","value":"Df/f over time of one or more ROIs. TimeSeries names should correspond to imaging plane names"}]},{"groups":[{"doc":"RoiResponseSeries object containing fluorescence data for a ROI","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence","attributes":[{"name":"help","doc":"Value is 'Fluorescence over time of one or more ROIs. TimeSeries names should correspond to imaging plane names'","dtype":"text","value":"Fluorescence over time of one or more ROIs. TimeSeries names should correspond to imaging plane names"}]},{"groups":[{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack)","quantity":"*","neurodata_type_inc":"ImageSeries"}],"name":"reference_images","doc":"Stores image stacks segmentation mask apply to."}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"name":"image_mask","doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"pixel_mask_index","doc":"index into pixel_mask","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"the pixel x-coordinate","name":"x","dtype":"uint"},{"doc":"the pixel y-coordinate","name":"y","dtype":"uint"},{"doc":"the weight of the pixel","name":"weight","dtype":"float"}],"name":"pixel_mask","doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"voxel_mask_index","doc":"index into voxel_mask","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"the voxel x-coordinate","name":"x","dtype":"uint"},{"doc":"the voxel y-coordinate","name":"y","dtype":"uint"},{"doc":"the voxel y-coordinate","name":"z","dtype":"uint"},{"doc":"the weight of the voxel","name":"weight","dtype":"float"}],"name":"voxel_mask","doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"The unique identifier for the rows in this dynamic table","neurodata_type_inc":"ElementIdentifiers"},{"doc":"The vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"The indices for the vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorIndex"}],"links":[{"name":"imaging_plane","doc":"link to ImagingPlane group from which this TimeSeries data was generated","target_type":"ImagingPlane"}],"doc":"results for image segmentation of a specific imaging plane","quantity":"+","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation","attributes":[{"name":"help","doc":"Value is 'Results from segmentation of an imaging plane'","dtype":"text","value":"Results from segmentation of an imaging plane"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation","attributes":[{"name":"help","doc":"Value is 'Stores groups of pixels that define regions of interest from one or more imaging planes'","dtype":"text","value":"Stores groups of pixels that define regions of interest from one or more imaging planes"}]},{"groups":[{"datasets":[{"dtype":"text","name":"description","doc":"Any notes or comments about the channel"},{"dtype":"float","name":"emission_lambda","doc":"Emission wavelength for channel in nm"}],"doc":"One of possibly many groups storing channel-specific data COMMENT: Name is arbitrary but should be meaningful","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel","attributes":[{"name":"help","doc":"Value is 'Metadata about an optical channel used to record from an imaging plane'","dtype":"text","value":"Metadata about an optical channel used to record from an imaging plane"}]}],"datasets":[{"dtype":"text","name":"description","doc":"Description of image_plane_X","quantity":"?"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength in nm"},{"dtype":"float","name":"imaging_rate","doc":"Rate images are acquired, in Hz."},{"dtype":"text","name":"indicator","doc":"Calcium indicator"},{"dtype":"text","name":"location","doc":"Location of image plane"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x|y|z"],["height","width","depth","x|y|z"]],"dtype":"float32","name":"manifold","doc":"Physical position of each pixel. COMMENT: 'xyz' represents the position of the pixel relative to the defined coordinate space","quantity":"?","attributes":[{"name":"conversion","doc":"Multiplier to get from stored values to specified unit (e.g., 1e-3 for millimeters)","required":false,"dtype":"float","default_value":1.0},{"name":"unit","doc":"Base unit that coordinates are stored in (e.g., Meters)","required":false,"dtype":"text","default_value":"Meter"}]},{"dtype":"text","name":"reference_frame","doc":"Describes position and reference frame of manifold based on position of first element in manifold. For example, text description of anatomical location or vectors needed to rotate to common anatomical axis (eg, AP/DV/ML). COMMENT: This field is necessary to interpret manifold. If manifold is not present then this field is not required","quantity":"?"}],"links":[{"name":"device","doc":"the device that was used to record from this electrode","target_type":"Device"}],"doc":"One of possibly many groups describing an imaging plane. COMMENT: Name is arbitrary but should be meaningful. It is referenced by TwoPhotonSeries and also ImageSegmentation and DfOverF interfaces","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane","attributes":[{"name":"help","doc":"Value is 'Metadata about an imaging plane'","dtype":"text","value":"Metadata about an imaging plane"}]},{"groups":[{"groups":[{"name":"corrected","doc":"Image stack with frames shifted to the common coordinates.","neurodata_type_inc":"ImageSeries"},{"name":"xy_translation","doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","neurodata_type_inc":"TimeSeries"}],"links":[{"name":"original","doc":"HDF5 Link to image series that is being registered.","target_type":"ImageSeries"}],"doc":"One of possibly many. Name should be informative.","quantity":"+","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack","attributes":[{"name":"help","doc":"Value is 'Reuslts from motion correction of an image stack'","dtype":"text","value":"Reuslts from motion correction of an image stack"}]}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection","attributes":[{"name":"help","doc":"Value is 'Image stacks whose frames have been shifted (registered) to account for motion'","dtype":"text","value":"Image stacks whose frames have been shifted (registered) to account for motion"}]}]}{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_phase_map","doc":"Phase response to stimulus on the first measured axis","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row|column"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_power_map","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_phase_map","doc":"Phase response to stimulus on the second measured axis","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_power_map","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null],"dims":["2"],"dtype":"text","name":"axis_descriptions","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta']"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"focal_depth_image","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"focal_depth","doc":"Focal depth offset, in meters","dtype":"float"},{"name":"format","doc":"Format of image. Right now only 'raw' supported","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"sign_map","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"vasculature_image","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"format","doc":"Format of image. Right now only 'raw' supported","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas.
Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy","attributes":[{"name":"help","doc":"Value is 'Intrinsic signal optical imaging or Widefield imaging for measuring retinotopy'","dtype":"text","value":"Intrinsic signal optical imaging or Widefield imaging for measuring retinotopy"}]}]}U{"namespaces":[{"doc":"NWB namespace","schema":[{"source":"nwb.base"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.0.2","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}x$././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.0.3_str_experimenter.nwb0000644000175100001730000043134014467767506022544 0ustar00runnerdockerHDF  2` TREEH:HEAP`H0 0 .speclocpHhTREEHEAPXPSNOD Hh(Pp P,H0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREE*HEAPXexperimenter@ @help=<=0?#]GCOLone experimenter 2019-11-27T17:32:05.899608-08:00ADDMEADDME 2019-11-27T17:32:05.899608-08:00 2019-11-27T17:32:05.899608-08:00=an NWB:N file for storing cellular-based neurophysiology data2.0.2 core NWBFile  {"groups":[{"datasets":[{"dtype":"float","name":"start_time","doc":"Start time of epoch, in seconds","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'start time of the epoch, in seconds'","dtype":"text","value":"start time of the epoch, in seconds"}]},{"dtype":"float","name":"stop_time","doc":"Stop time of epoch, in seconds","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'stop time of the epoch, in seconds'","dtype":"text","value":"stop time of the epoch, in seconds"}]},{"dtype":"text","name":"tags","doc":"User-defined tags that identify events. Tags are to help identify or categorize events.","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'user-defined tags'","dtype":"text","value":"user-defined tags"}]},{"name":"tags_index","doc":"Index for tags","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries data[] field. COMMENT: This can be used to calculate location in TimeSeries timestamp[] field","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"name":"timeseries","doc":"An index into a TimeSeries object","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"name":"help","doc":"Value is 'Data on how an epoch applies to a time series'","dtype":"text","value":"Data on how an epoch applies to a time series"}]},{"name":"timeseries_index","doc":"Index for timeseries","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals","attributes":[{"name":"help","doc":"Value is 'A general epoch object'","dtype":"text","value":"A general epoch object"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}`SNOD2#]x2#]2#]2#]acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecifications3#]   *H  &{B{-{{5@V#8@VS {]1@V@VU@VSNODh-(  0 x(.8/p=0?8  1 H nwb_version H namespace Hneurodata_type PTREEhBHEAPXP?coreH?ATREEpFHEAPXB2.0.2HSNOD??ACETREEspQHEAP`ySNODCCE3#]GCOL8**{"datasets":[{"doc":"An abstract data type for a dataset","neurodata_type_def":"NWBData","attributes":[{"name":"help","doc":"Short description of what this type of Interface contains.","dtype":"text"}]},{"doc":"Pointers that index data values","neurodata_type_inc":"NWBData","neurodata_type_def":"Index","attributes":[{"name":"help","doc":"a help string","dtype":"text","value":"indexes into a list of values for a list of elements"},{"name":"target","doc":"the target dataset that this index applies to","dtype":{"target_type":"NWBData","reftype":"object"}}]},{"doc":"Data values indexed by pointer","neurodata_type_inc":"NWBData","neurodata_type_def":"VectorData","attributes":[{"name":"help","doc":"a help string","dtype":"text","value":"Values for a list of elements"},{"name":"description","doc":"A short description of what these vectors are","dtype":"text"}]},{"doc":"Pointers that index data values","neurodata_type_inc":"Index","neurodata_type_def":"VectorIndex","attributes":[{"name":"target","doc":"the target dataset that this index applies to","dtype":{"target_type":"VectorData","reftype":"object"}},{"name":"help","doc":"a help string","dtype":"text","value":"indexes into a list of values for a list of elements"}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"a unique identifier for each element","default_name":"element_id","neurodata_type_inc":"NWBData","neurodata_type_def":"ElementIdentifiers","attributes":[{"name":"help","doc":"a help string","dtype":"text","value":"unique identifiers for a list of elements"}]},{"dtype":"int","doc":"a region/index into a DynamicTable","neurodata_type_inc":"VectorData","neurodata_type_def":"DynamicTableRegion","attributes":[{"name":"help","doc":"value is 'a subset (i.e. slice or region) of a DynamicTable'","dtype":"text","value":"a subset (i.e. slice or region) of a DynamicTable"},{"name":"table","doc":"a reference to the DynamicTable this region applies to","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"name":"description","doc":"Description of what this table region points to","dtype":"text"}]},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["num_x","num_y"],["num_x","num_y","(r, g, b)"],["num_x","num_y","(r, g, b, a)"]],"doc":"Image base type.","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_def":"NWBContainer","attributes":[{"name":"help","doc":"Short description of what this type of NWBContainer contains.","dtype":"text"}]},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface","attributes":[{"name":"help","doc":"Short description of what this type of NWBContainer contains.","dtype":"text"}]},{"groups":[{"name":"sync","doc":"Lab specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. COMMENT: This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","quantity":"?"}],"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"uint8","name":"control","doc":"Numerical labels that apply to each element in data[]. COMMENT: Optional field. If present, the control array should have the same number of elements as data[].","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","name":"control_description","doc":"Description of each control value. COMMENT: Array length should be as long as the highest number in control minus one, generating an zero-based indexed array for control values.","quantity":"?"},{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"name":"data","doc":"Data values. Can also store binary data (eg, image frames) COMMENT: This field may be a link to data stored in an external file, especially in the case of raw data.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"dtype":"float64","name":"starting_time","doc":"The timestamp of the first sample. COMMENT: When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate.","quantity":"?","attributes":[{"name":"rate","doc":"Sampling rate, in Hz COMMENT: Rate information is stored in Hz","dtype":"float32"},{"name":"unit","doc":"Value is 'Seconds'","dtype":"text","value":"Seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data.COMMENT: Timestamps here have all been corrected to the common experiment master-clock. Time is stored as seconds and all timestamps are relative to experiment start time.","quantity":"?","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Value is 'Seconds'","dtype":"text","value":"Seconds"}]}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"},{"name":"help","doc":"Value is 'General time series object'","dtype":"text","value":"General time series object"}]},{"groups":[{"doc":"Interface objects containing data output from processing steps","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"doc":"Module. Name should be descriptive. Stores a collection of related data organized by contained interfaces. Each interface is a contract specifying content related to a particular type of data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"name":"description","doc":"Description of Module","dtype":"text"},{"name":"help","doc":"Value is 'A collection of analysis outputs from processing of data'","dtype":"text","value":"A collection of analysis outputs from processing of data"}]},{"datasets":[{"doc":"Images stored in this NWBDataInterface","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A NWBDataInterface for storing images that have some relationship","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"name":"description","doc":"Description of images in this container","dtype":"text"},{"name":"help","doc":"Value is 'A collection of images that have some meaningful relationship'","dtype":"text","value":"A collection of images that have some meaningful relationship"}]},{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"The unique identifier for the rows in this dynamic table","neurodata_type_inc":"ElementIdentifiers"},{"doc":"The vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"The indices for the vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorIndex"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). Apart from a column that contains unique identifiers for each row there are no other required datasets. Users are free to add any number of VectorData objects here. Table functionality is already supported through compound types, which is analogous to storing an array-of-structs. DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable. For example, DynamicTable was originally developed for storing trial data and spike unit metadata. Both of these use cases are expected to produce relatively small tables, so the spatial locality of multiple datasets present in a DynamicTable is not expected to have a significant performance impact. Additionally, requirements of trial and unit metadata tables are sufficiently diverse that performance implications can be overlooked in favor of usability.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DynamicTable","attributes":[{"name":"help","doc":"Value is 'A column-centric table'","dtype":"text","value":"A column-centric table"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}SNODTGXxh@NHt 3#]03#]@3#]P3#]`3#]nwb.basenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOL@&{"datasets":[{"shape":[null,null],"dims":["y","x"],"doc":"Grayscale image","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]},{"shape":[null,null,3],"dims":["y","x","R,G,B"],"doc":"Color image","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]},{"shape":[null,null,4],"dims":["y","x","R,G,B,A"],"doc":"Color image with transparency","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","y","x"],["frame","z","y","x"]],"dtype":"numeric","name":"data","doc":"Either binary data containing image or empty.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","name":"dimension","doc":"Number of pixels on x, y, (and z) axes.","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","name":"external_file","doc":"Path or URL to one or more external file(s). Field only present if format=external. NOTE: this is only relevant if the image is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another HDF5 file and that file is HDF5 linked to this file.","quantity":"?","attributes":[{"name":"starting_frame","doc":"Each entry is the frame number (within the full ImageSeries) of the first frame in the corresponding external_file entry. This serves as an index to what frames each file contains, allowing random access.Zero-based indexing is used. (The first element will always be zero).","dtype":"int","shape":[null],"dims":["num_files"]}]},{"dtype":"text","name":"format","doc":"Format of image. If this is 'external' then the field external_file contains the path or URL information to that file. For tiff, png, jpg, etc, the binary representation of the image is stored in data. If the format is raw then the fields bit_per_pixel and dimension are used. For raw images, only a single channel is stored (eg, red).","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the HDF5 file in a raw format while other times it will be stored as an external image file in the host file system. The data field will either be binary data or empty. TimeSeries::data array structure: [frame] [y][x] or [frame][z][y][x].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries","attributes":[{"name":"help","doc":"Value is 'Storage object for time-series 2-D image data'","dtype":"text","value":"Storage object for time-series 2-D image data"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"links":[{"name":"masked_imageseries","doc":"Link to ImageSeries that mask is applied to.","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The data[] array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries","attributes":[{"name":"help","doc":"Value is 'An alpha mask that is applied to a presented visual stimulus'","dtype":"text","value":"An alpha mask that is applied to a presented visual stimulus"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"float32","name":"distance","doc":"Distance from camera/monitor to target/eye.","quantity":"?"},{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area (meters).","quantity":"?"},{"dtype":"text","name":"orientation","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (eg, how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries","attributes":[{"name":"help","doc":"Value is 'Time-series image stack for optical recording or stimulus'","dtype":"text","value":"Time-series image stack for optical recording or stimulus"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int","name":"data","doc":"Index of the frame in the referenced ImageSeries.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]}],"links":[{"name":"indexed_timeseries","doc":"HDF5 link to TimeSeries containing images that are indexed.","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries","attributes":[{"name":"help","doc":"Value is 'A sequence that is generated from an existing image stack. Frames can be presented in an arbitrary order. The data[] field stores frame number in reference stack'","dtype":"text","value":"A sequence that is generated from an existing image stack. Frames can be presented in an arbitrary order. The data[] field stores frame number in reference stack"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]}]}B{"groups":[{"groups":[{"groups":[{"doc":"Any objects representing acquired data","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"name":"acquisition","doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. COMMENT: This group is read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external HDF5 files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. MORE_INFO: Acquired data includes tracking and experimental data streams (ie, everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate HDF5 file that is linked to by the file being used for processing and analysis."},{"groups":[{"doc":"Custom analysis results","quantity":"*","neurodata_type_inc":"NWBContainer"}],"name":"analysis","doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. COMMENT: To facilitate sharing analysis data between labs, the contents here should be stored in standard types (eg, INCF types) and appropriately documented. MORE_INFO: The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs."},{"groups":[{"doc":"Intermediate analysis of acquired data","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"name":"processing","doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. COMMENT: Modules are defined below. They can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. MORE_INFO: 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis. These are performed using Modules, as defined above. All modules reside in the processing group."},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"presentation","doc":"Stimuli presented during the experiment."},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"templates","doc":"Template stimuli. COMMENT: Time stamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame."}],"name":"stimulus","doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus) COMMENT: This group is read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. MORE_INFO: Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be HDF5-linked to a remote library file."},{"groups":[{"doc":"place-holder than can be extended so that lab-specific meta-data can be placed in /general","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData","attributes":[{"name":"help","doc":"Short description of what this type of NWBContainer contains.","dtype":"text"}]},{"groups":[{"doc":"One of possibly many. Information about device and device description.","quantity":"+","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"name":"help","doc":"Value is 'A recording device e.g. amplifier'.","dtype":"text","value":"A recording device e.g. amplifier"}]}],"name":"devices","doc":"Description of hardware devices used during experiment. COMMENT: Eg, monitors, ADC boards, microscopes, etc","quantity":"?"},{"datasets":[{"dtype":"text","name":"age","doc":"Age of subject","quantity":"?"},{"dtype":"isodatetime","name":"date_of_birth","doc":"can be supplied instead of age","quantity":"?"},{"dtype":"text","name":"description","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","quantity":"?"},{"dtype":"text","name":"genotype","doc":"Genetic strain COMMENT: If absent, assume Wild Type (WT)","quantity":"?"},{"dtype":"text","name":"sex","doc":"Gender of subject","quantity":"?"},{"dtype":"text","name":"species","doc":"Species of subject","quantity":"?"},{"dtype":"text","name":"subject_id","doc":"ID of animal/person used/participating in experiment (lab convention)","quantity":"?"},{"dtype":"text","name":"weight","doc":"Weight at time of experiment, at time of surgery and at other important times","quantity":"?"}],"name":"subject","doc":"Information about the animal or person from which the data was measured.","quantity":"?","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject","attributes":[{"name":"help","doc":"Value is 'Information about the subject'","dtype":"text","value":"Information about the subject"}]},{"groups":[{"doc":"One of possibly many groups, one for each electrode group.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float","name":"x","doc":"the x coordinate of the channel location","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the x coordinate of the channel location'","dtype":"text","value":"the x coordinate of the channel location"}]},{"dtype":"float","name":"y","doc":"the y coordinate of the channel location","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the y coordinate of the channel location'","dtype":"text","value":"the y coordinate of the channel location"}]},{"dtype":"float","name":"z","doc":"the z coordinate of the channel location","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the z coordinate of the channel location'","dtype":"text","value":"the z coordinate of the channel location"}]},{"dtype":"float","name":"imp","doc":"the impedance of the channel","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the impedance of the channel'","dtype":"text","value":"the impedance of the channel"}]},{"dtype":"ascii","name":"location","doc":"the location of channel within the subject e.g. brain region","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the location of channel within the subject e.g. brain region'","dtype":"text","value":"the location of channel within the subject e.g. brain region"}]},{"dtype":"float","name":"filtering","doc":"description of hardware filtering","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'description of hardware filtering'","dtype":"text","value":"description of hardware filtering"}]},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"group","doc":"a reference to the ElectrodeGroup this electrode is a part of","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'a reference to the ElectrodeGroup this electrode is a part of'","dtype":"text","value":"a reference to the ElectrodeGroup this electrode is a part of"}]},{"dtype":"ascii","name":"group_name","doc":"name of the ElectrodeGroup this electrode is a part of","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the name of the ElectrodeGroup this electrode is a part of'","dtype":"text","value":"the name of the ElectrodeGroup this electrode is a part of"}]}],"name":"electrodes","doc":"A table of all electrodes (i.e. channels) used for recording.","quantity":"?","neurodata_type_inc":"DynamicTable"}],"name":"extracellular_ephys","doc":"Metadata related to extracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"One of possibly many. COMMENT: Name should be informative.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"name":"sweep_table","doc":"The table which groups different PatchClampSeries together.","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","name":"filtering","doc":"Description of filtering used. COMMENT: Includes filtering type and parameters, frequency fall- off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","quantity":"?"}],"name":"intracellular_ephys","doc":"Metadata related to intracellular electrophysiology","quantity":"?"},{"groups":[{"doc":"One of possibly many groups describing an optogenetic stimulation site. COMMENT: Name is arbitrary but should be meaningful. Name is referenced by OptogeneticSeries.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"name":"optogenetics","doc":"Metadata describing optogenetic stimuluation","quantity":"?"},{"groups":[{"doc":"One of possibly many groups describing an imaging plane. COMMENT: Name is arbitrary but should be meaningful. It is referenced by TwoPhotonSeries and also ImageSegmentation and DfOverF interfaces.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"name":"optophysiology","doc":"Metadata related to optophysiology.","quantity":"?"}],"datasets":[{"dtype":"text","name":"data_collection","doc":"Notes about data collection and analysis.COMMENT: Can be from Methods","quantity":"?"},{"dtype":"text","name":"experiment_description","doc":"General description of the experiment.COMMENT: Can be from Methods","quantity":"?"},{"dtype":"text","name":"experimenter","doc":"Name of person who performed the experiment.COMMENT: More than one person OK. Can specify roles of different people involved.","quantity":"?"},{"dtype":"text","name":"institution","doc":"Institution(s) where experiment was performed","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","name":"keywords","doc":"Terms to search over","quantity":"?"},{"dtype":"text","name":"lab","doc":"Lab where experiment was performed","quantity":"?"},{"dtype":"text","name":"notes","doc":"Notes about the experiment. COMMENT: Things particular to this experiment","quantity":"?"},{"dtype":"text","name":"pharmacology","doc":"Description of drugs used, including how and when they were administered. COMMENT: Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","quantity":"?"},{"dtype":"text","name":"protocol","doc":"Experimental protocol, if applicable. COMMENT: E.g., include IACUC protocol.","quantity":"?"},{"dtype":"text","name":"related_publications","doc":"Publication information. COMMENT: PMID, DOI, URL, etc. If multiple, concatenate together and describe which is which. such as PMID, DOI, URL, etc","quantity":"?"},{"dtype":"text","name":"session_id","doc":"Lab-specific ID for the session.COMMENT: Only 1 session_id per file, with all time aligned to experiment start time.","quantity":"?"},{"dtype":"text","name":"slices","doc":"Description of slices, including information about preparation thickness, orientation, temperature and bath solution","quantity":"?"},{"dtype":"text","name":"source_script","doc":"Script file used to create this NWB file.","quantity":"?","attributes":[{"name":"file_name","doc":"Name of script file","dtype":"text"}]},{"dtype":"text","name":"stimulus","doc":"Notes about stimuli, such as how and where presented. COMMENT: Can be from Methods.","quantity":"?"},{"dtype":"text","name":"surgery","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery. COMMENT: Much can be copied from Methods.","quantity":"?"},{"dtype":"text","name":"virus","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","quantity":"?"}],"name":"general","doc":"Experimental metadata, including protocol, notes and description of hardware device(s). COMMENT: The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. MORE_INFO: General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them."},{"groups":[{"name":"epochs","doc":"divisions in time marking experimental stages or sub-divisions of a single recording session","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"trials","doc":"repeated experimental events that have a logical grouping","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"invalid_times","doc":"time intervals that should be removed from analysis","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"an optional additional table for describing other experimental time intervals","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"name":"intervals","doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","quantity":"?"},{"name":"units","doc":"Data about units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","name":"file_create_date","doc":"A record of the date the file was created and of subsequent modifications. COMMENT: - The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00 - Dates stored in UTC end in \"Z\" with no timezone offset. - Date accuracy is up to milliseconds. - The file can be created after the experiment was run, so this may differ from the experiment start time. - Each modification to the nwb file adds a new entry to the array."},{"dtype":"text","name":"identifier","doc":"A unique text identifier for the file. COMMENT: Eg, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files."},{"dtype":"text","name":"session_description","doc":"One or two sentences describing the experiment and data in the file."},{"dtype":"isodatetime","name":"session_start_time","doc":"Date and time of the experiment/session start. COMMENT: - The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00 - Dates stored in UTC end in \"Z\" with no timezone offset. - Date accuracy is up to milliseconds."},{"dtype":"isodatetime","name":"timestamps_reference_time","doc":"Date and time corresponding to time zero of all timestamps. COMMENT: - The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00 - Dates stored in UTC end in \"Z\" with no timezone offset. - Date accuracy is up to milliseconds. - All times stored in the file use this time as reference (ie, time zero)."}],"name":"root","doc":"Top level of NWB file.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"name":"help","doc":"Value is 'an NWB:N file for storing cellular-based neurophysiology data'","dtype":"text","value":"an NWB:N file for storing cellular-based neurophysiology data"},{"name":"nwb_version","doc":"File version string. COMMENT: Eg, NWB-1.0.0. This will be the name of the format with trailing major, minor and patch numbers.","dtype":"text","value":"2.0.2"}]}]}-{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"Values of each feature at each time.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"feature_units","doc":"Units of each feature.","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"features","doc":"Description of the features represented in TimeSeries::data."}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries","attributes":[{"name":"help","doc":"Value is 'Features of an applied stimulus. This is useful when storing the raw stimulus is impractical'","dtype":"text","value":"Features of an applied stimulus. This is useful when storing the raw stimulus is impractical"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","name":"data","doc":"Annotations made during an experiment.","attributes":[{"name":"resolution","doc":"Value is -1.0","dtype":"float","value":-1.0},{"name":"unit","doc":"Value is 'n/a'","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores, eg, user annotations made during an experiment. The TimeSeries::data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries","attributes":[{"name":"help","doc":"Value is 'Time-stamped annotations about an experiment'","dtype":"text","value":"Time-stamped annotations about an experiment"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","name":"data","doc":">0 if interval started, <0 if interval ended.","attributes":[{"name":"resolution","doc":"Value is -1.0","dtype":"float","value":-1.0},{"name":"unit","doc":"Value is 'n/a'","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries","attributes":[{"name":"help","doc":"Value is 'Stores the start and stop times for events'","dtype":"text","value":"Stores the start and stop times for events"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"groups":[{"datasets":[{"dtype":"text","name":"band_name","doc":"the name of the band e.g. theta","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the name of the band e.g. theta'","dtype":"text","value":"the name of the band e.g. theta"}]},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float","name":"band_limits","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center'","dtype":"text","value":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center"}]},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_mean","doc":"The mean Gaussian filters in Hz","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"The mean Gaussian filters in Hz","dtype":"text","value":"The mean Gaussian filters in Hz"}]},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_stdev","doc":"The standard devaition of Gaussian filters in Hz","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"The standard devaition of Gaussian filters in Hz","dtype":"text","value":"The standard devaition of Gaussian filters in Hz"}]}],"name":"bands","doc":"A table for describing the bands that this series was generated from. There should be one row in this table for each band","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","name":"data","doc":"The data goes here","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"dtype":"text","name":"metric","doc":"recommended: phase, amplitude, power"}],"links":[{"name":"source_timeseries","doc":"HDF5 link to TimesSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here","target_type":"TimeSeries","quantity":"?"}],"doc":"Holds spectral analysis of a timeseries. For instance of LFP or a speech signal","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries","attributes":[{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"},{"name":"help","doc":"Value is 'General time series object'","dtype":"text","value":"General time series object"}]},{"datasets":[{"name":"spike_times_index","doc":"the index into the spike_times dataset","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"double","name":"spike_times","doc":"the spike times for each unit","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"obs_intervals_index","doc":"the index into the obs_intervals dataset","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"double","name":"obs_intervals","doc":"the observation intervals for each unit","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"electrodes_index","doc":"the index into electrodes","quantity":"?","neurodata_type_inc":"VectorIndex"},{"name":"electrodes","doc":"the electrode that each spike unit came from","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"electrode_group","doc":"the electrode group that each spike unit came from","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_mean","doc":"the spike waveform mean for each spike unit","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_sd","doc":"the spike waveform standard deviation for each spike unit","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units","attributes":[{"name":"help","doc":"Value is 'Data about spiking units'","dtype":"text","value":"Data about spiking units"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"2-D array storing position or direction relative to some reference frame.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"meter"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"dtype":"text","name":"reference_frame","doc":"Description defining what exactly 'straight-ahead' means.","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries","attributes":[{"name":"help","doc":"Value is: Stores points in space over time. The data[] array structure is [num samples][num spatial dimensions]","dtype":"text","value":"Stores points in space over time. The data[] array structure is [num samples][num spatial dimensions]"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs","attributes":[{"name":"help","doc":"Value is 'General container for storing behavioral epochs'","dtype":"text","value":"General container for storing behavioral epochs"}]},{"groups":[{"doc":"TimeSeries object containing irregular behavioral events","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents","attributes":[{"name":"help","doc":"Value is 'Position data, whether along the x, xy or xyz axis'","dtype":"text","value":"Position data, whether along the x, xy or xyz axis"}]},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data.See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries","attributes":[{"name":"help","doc":"Value is 'General container for storing continuously sampled behavioral data.'","dtype":"text","value":"General container for storing continuously sampled behavioral data."}]},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking","attributes":[{"name":"help","doc":"Value is 'Eye-tracking data, representing pupil size'","dtype":"text","value":"Eye-tracking data, representing pupil size"}]},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking","attributes":[{"name":"help","doc":"Value is 'Eye-tracking data, representing direction of gaze'","dtype":"text","value":"Eye-tracking data, representing direction of gaze"}]},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection","attributes":[{"name":"help","doc":"Value is 'Direction as measured radially. Spatial series reference frame should indicate which direction corresponds to zero and what is the direction of positive rotation'","dtype":"text","value":"Direction as measured radially. Spatial series reference frame should indicate which direction corresponds to zero and what is the direction of positive rotation"}]},{"groups":[{"doc":"SpatialSeries object containing position data","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position","attributes":[{"name":"help","doc":"Value is 'Position data, whether along the x, xy or xyz axis'","dtype":"text","value":"Position data, whether along the x, xy or xyz axis"}]}]}S {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Applied power for optogenetic stimulus.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"watt"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]}],"links":[{"name":"site","doc":"link to OptogeneticStimulusSite group that describes the site to which this stimulus was applied","target_type":"OptogeneticStimulusSite"}],"doc":"Optogenetic stimulus. The data[] field is in unit of watts.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries","attributes":[{"name":"help","doc":"Value is 'Optogenetic stimulus'","dtype":"text","value":"Optogenetic stimulus"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of site"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength in nm"},{"dtype":"text","name":"location","doc":"Location of stimulation site"}],"links":[{"name":"device","doc":"Device that generated the stimulus","target_type":"Device"}],"doc":"One of possibly many groups describing an optogenetic stimulation site. COMMENT: Name is arbitrary but should be meaningful. Name is referenced by OptogeneticSeries","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite","attributes":[{"name":"help","doc":"Value is 'Metadata about an optogenetic stimulus site'","dtype":"text","value":"Metadata about an optogenetic stimulus site"}]}]}p3#]3#]3#]SNOD8hvxPO(XuHxw`PRS3#]3#]3#]GCOL5{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Recorded voltage data.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"volt"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"name":"electrodes","doc":"the electrodes that this series was generated from","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Stores acquired voltage data from extracellular recordings. The data field of an ElectricalSeries is an int or float array storing data in Volts. TimeSeries::data array structure: :blue:`[num times] [num channels] (or [num_times] for single electrode).`","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"name":"help","doc":"Value is 'Stores acquired voltage data from extracellular recordings'","dtype":"text","value":"Stores acquired voltage data from extracellular recordings"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Spike waveforms.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"volt"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data.COMMENT: Timestamps here have all been corrected to the common experiment master-clock. Time is stored as seconds and all timestamps are relative to experiment start time. This is added here so that the timestamps is required for SpikeEventTimes.","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Value is 'Seconds'","dtype":"text","value":"Seconds"}]}],"doc":"Stores 'snapshots' of spike events (i.e., threshold crossings) in data. This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describing how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries","attributes":[{"name":"help","doc":"Value is 'Snapshots of spike events from data.'","dtype":"text","value":"Snapshots of spike events from data."},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"text","name":"waveform_filtering","doc":"Filtering applied to data before generating mean/sd"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_mean","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_sd","doc":"Stdev of waveforms for each cluster, using the same indices as in mean"}],"links":[{"name":"clustering_interface","doc":"HDF5 link to Clustering interface that was the source of the clustered data","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms","attributes":[{"name":"help","doc":"Value is 'Mean waveform shape of clusters. Waveforms should be high-pass filtered (ie, not the same bandpass filter used waveform analysis and clustering)'","dtype":"text","value":"DEPRECATED Mean waveform shape of clusters. Waveforms should be high-pass filtered (ie, not the same bandpass filter used waveform analysis and clustering)"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)"},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"num","doc":"Cluster number of each event"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","name":"peak_over_rms","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric)."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module."}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering","attributes":[{"name":"help","doc":"Value is 'Clustered spike data, whether from automatic clustering tools (eg, klustakwik) or as a result of manual sorting'","dtype":"text","value":"DEPRECATED Clustered spike data, whether from automatic clustering tools (eg, klustakwik) or as a result of manual sorting"}]},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","name":"description","doc":"Description of features (eg, ''PC1'') for each of the extracted features."},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","name":"features","doc":"Multi-dimensional array of features extracted from each event."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of events that features correspond to (can be a link)."},{"name":"electrodes","doc":"the electrodes that this series was generated from","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEvent TimeSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction","attributes":[{"name":"help","doc":"Value is 'Container for salient features of detected events'","dtype":"text","value":"Container for salient features of detected events"}]},{"datasets":[{"dtype":"text","name":"detection_method","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values."},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"source_idx","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. Module description should define what is meant by time of event (e.g., .25msec before action potential peak, zero-crossing time, etc). The index points to each event from the raw data"},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Timestamps of events, in Seconds","attributes":[{"name":"unit","doc":"The string ''Seconds''","required":false,"dtype":"text","default_value":"Seconds"}]}],"links":[{"name":"source_electricalseries","doc":"HDF5 link to ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to mandate that information be stored here","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection","attributes":[{"name":"help","doc":"Value is 'Detected spike events from voltage trace(s)'","dtype":"text","value":"Detected spike events from voltage trace(s)"}]},{"groups":[{"doc":"SpikeEventSeries object containing detected spike event waveforms","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform","attributes":[{"name":"help","doc":"Value is 'Waveform of detected extracellularly recorded spike events'","dtype":"text","value":"Waveform of detected extracellularly recorded spike events"}]},{"groups":[{"doc":"ElectricalSeries object containing filtered electrophysiology data","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Ephys data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys","attributes":[{"name":"help","doc":"Value is 'Ephys data from one or more channels that is subjected to filtering, such as for gamma or theta oscillations (LFP has its own interface). Filter properties should be noted in the ElectricalSeries'","dtype":"text","value":"Ephys data from one or more channels that is subjected to filtering, such as for gamma or theta oscillations (LFP has its own interface). Filter properties should be noted in the ElectricalSeries"}]},{"groups":[{"doc":"ElectricalSeries object containing LFP data for one or more channels","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries description or comments field.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP","attributes":[{"name":"help","doc":"Value is 'LFP data from one or more channels. Filter properties should be noted in the ElectricalSeries'","dtype":"text","value":"LFP data from one or more channels. Filter properties should be noted in the ElectricalSeries"}]},{"links":[{"name":"device","doc":"the device that was used to record from this electrode group","target_type":"Device","quantity":"?"}],"doc":"One of possibly many groups, one for each electrode group.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"name":"help","doc":"Value is 'Metadata about a physical grouping of channels'","dtype":"text","value":"A physical grouping of channels"},{"name":"description","doc":"description of this electrode group","dtype":"text"},{"name":"location","doc":"description of location of this electrode group","dtype":"text"}]}]}#8{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Recorded voltage or current.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"dtype":"float","name":"gain","doc":"Units: Volt/Amp (v-clamp) or Volt/Volt (c-clamp)","quantity":"?"}],"links":[{"name":"electrode","doc":"link to IntracellularElectrode group that describes th electrode that was used to apply or record this data","target_type":"IntracellularElectrode"}],"doc":"Stores stimulus or response current or voltage. Superclass definition for patch-clamp data (this class should not be instantiated directly).","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"name":"help","doc":"Value is 'Superclass definition for patch-clamp data'","dtype":"text","value":"Superclass definition for patch-clamp data"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"float32","name":"bias_current","doc":"Unit: Amp","quantity":"?"},{"dtype":"float32","name":"bridge_balance","doc":"Unit: Ohm","quantity":"?"},{"dtype":"float32","name":"capacitance_compensation","doc":"Unit: Farad","quantity":"?"}],"doc":"Stores voltage data recorded from intracellular current-clamp recordings. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries","attributes":[{"name":"help","doc":"Value is 'Voltage recorded from cell during current-clamp recording'","dtype":"text","value":"Voltage recorded from cell during current-clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"doc":"Stores recorded voltage data from intracellular recordings when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"name":"help","doc":"Value is 'Voltage from intracellular recordings when all current and amplifier settings are off'","dtype":"text","value":"Voltage from intracellular recordings when all current and amplifier settings are off"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"doc":"Aliases to standard PatchClampSeries. Its functionality is to better tag PatchClampSeries for machine (and human) readability of the file.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries","attributes":[{"name":"help","doc":"Value is 'Stimulus current applied during current clamp recording'","dtype":"text","value":"Stimulus current applied during current clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"float32","name":"capacitance_fast","doc":"Unit: Farad","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Farad"}]},{"dtype":"float32","name":"capacitance_slow","doc":"Unit: Farad","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Farad"}]},{"dtype":"float32","name":"resistance_comp_bandwidth","doc":"Unit: Hz","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Hz"}]},{"dtype":"float32","name":"resistance_comp_correction","doc":"Unit: %","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"percent"}]},{"dtype":"float32","name":"resistance_comp_prediction","doc":"Unit: %","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"percent"}]},{"dtype":"float32","name":"whole_cell_capacitance_comp","doc":"Unit: Farad","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Farad"}]},{"dtype":"float32","name":"whole_cell_series_resistance_comp","doc":"Unit: Ohm","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Ohm"}]}],"doc":"Stores current data recorded from intracellular voltage-clamp recordings. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries","attributes":[{"name":"help","doc":"Value is 'Current recorded from cell during voltage-clamp recording'","dtype":"text","value":"Current recorded from cell during voltage-clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"doc":"Aliases to standard PatchClampSeries. Its functionality is to better tag PatchClampSeries for machine (and human) readability of the file.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries","attributes":[{"name":"help","doc":"Value is 'Stimulus voltage applied during voltage clamp recording'","dtype":"text","value":"Stimulus voltage applied during voltage clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Recording description, description of electrode (e.g., whole-cell, sharp, etc)COMMENT: Free-form text (can be from Methods)"},{"dtype":"text","name":"filtering","doc":"Electrode specific filtering.","quantity":"?"},{"dtype":"text","name":"initial_access_resistance","doc":"Initial access resistance","quantity":"?"},{"dtype":"text","name":"location","doc":"Area, layer, comments on estimation, stereotaxis coordinates (if in vivo, etc)","quantity":"?"},{"dtype":"text","name":"resistance","doc":"Electrode resistance COMMENT: unit: Ohm","quantity":"?"},{"dtype":"text","name":"seal","doc":"Information about seal used for recording","quantity":"?"},{"dtype":"text","name":"slice","doc":"Information about slice used for recording","quantity":"?"}],"links":[{"name":"device","doc":"the device that was used to record from this electrode","target_type":"Device"}],"doc":"One of possibly many. COMMENT: Name should be informative.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode","attributes":[{"name":"help","doc":"Value is 'Metadata about an intracellular electrode'","dtype":"text","value":"Metadata about an intracellular electrode"}]},{"datasets":[{"dtype":"uint64","name":"sweep_number","doc":"The sweep number of the PatchClampSeries in that row.","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'The sweep number of the PatchClampSeries in that row'","dtype":"text","value":"The sweep number of the PatchClampSeries in that row"}]},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"name":"series","doc":"The PatchClampSeries with the sweep number in that row","neurodata_type_inc":"VectorData","attributes":[{"name":"help","doc":"Value is 'The PatchClampSeries with the sweep number in that row'","dtype":"text","value":"The PatchClampSeries with the sweep number in that row"}]},{"name":"series_index","doc":"Index for series","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable","attributes":[{"name":"help","doc":"Value is 'The table which groups different PatchClampSeries together'","dtype":"text","value":"The table which groups different PatchClampSeries together"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}]1{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":["width|height","width|height|depth"],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area (meters).","quantity":"?"}],"links":[{"name":"imaging_plane","doc":"link to ImagingPlane group from which this TimeSeries data was generated","target_type":"ImagingPlane"}],"doc":"A special case of optical imaging.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"name":"help","doc":"Value is 'Image stack recorded from 2-photon microscope'","dtype":"text","value":"Image stack recorded from 2-photon microscope"},{"name":"pmt_gain","doc":"Photomultiplier gain","required":false,"dtype":"float32"},{"name":"scan_line_rate","doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","required":false,"dtype":"float32"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","name":"data","doc":"Signals from ROIs","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"name":"rois","doc":"a dataset referencing into an ROITable containing information on the ROIs stored in this timeseries","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. Each row in data[] should correspond to the signal from one ROI.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries","attributes":[{"name":"help","doc":"Value is 'ROI responses over an imaging plane. Each element on the second dimension of data[] should correspond to the signal from one ROI'","dtype":"text","value":"ROI responses over an imaging plane. Each element on the second dimension of data[] should correspond to the signal from one ROI"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"groups":[{"doc":"RoiResponseSeries object containing dF/F for a ROI","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF","attributes":[{"name":"help","doc":"Value is 'Df/f over time of one or more ROIs. TimeSeries names should correspond to imaging plane names'","dtype":"text","value":"Df/f over time of one or more ROIs. TimeSeries names should correspond to imaging plane names"}]},{"groups":[{"doc":"RoiResponseSeries object containing fluorescence data for a ROI","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence","attributes":[{"name":"help","doc":"Value is 'Fluorescence over time of one or more ROIs. TimeSeries names should correspond to imaging plane names'","dtype":"text","value":"Fluorescence over time of one or more ROIs. TimeSeries names should correspond to imaging plane names"}]},{"groups":[{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack)","quantity":"*","neurodata_type_inc":"ImageSeries"}],"name":"reference_images","doc":"Stores image stacks segmentation mask apply to."}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"name":"image_mask","doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"pixel_mask_index","doc":"index into pixel_mask","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"the pixel x-coordinate","name":"x","dtype":"uint"},{"doc":"the pixel y-coordinate","name":"y","dtype":"uint"},{"doc":"the weight of the pixel","name":"weight","dtype":"float"}],"name":"pixel_mask","doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"voxel_mask_index","doc":"index into voxel_mask","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"the voxel x-coordinate","name":"x","dtype":"uint"},{"doc":"the voxel y-coordinate","name":"y","dtype":"uint"},{"doc":"the voxel y-coordinate","name":"z","dtype":"uint"},{"doc":"the weight of the voxel","name":"weight","dtype":"float"}],"name":"voxel_mask","doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"The unique identifier for the rows in this dynamic table","neurodata_type_inc":"ElementIdentifiers"},{"doc":"The vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"The indices for the vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorIndex"}],"links":[{"name":"imaging_plane","doc":"link to ImagingPlane group from which this TimeSeries data was generated","target_type":"ImagingPlane"}],"doc":"results for image segmentation of a specific imaging plane","quantity":"+","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation","attributes":[{"name":"help","doc":"Value is 'Results from segmentation of an imaging plane'","dtype":"text","value":"Results from segmentation of an imaging plane"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation","attributes":[{"name":"help","doc":"Value is 'Stores groups of pixels that define regions of interest from one or more imaging planes'","dtype":"text","value":"Stores groups of pixels that define regions of interest from one or more imaging planes"}]},{"groups":[{"datasets":[{"dtype":"text","name":"description","doc":"Any notes or comments about the channel"},{"dtype":"float","name":"emission_lambda","doc":"Emission wavelength for channel in nm"}],"doc":"One of possibly many groups storing channel-specific data COMMENT: Name is arbitrary but should be meaningful","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel","attributes":[{"name":"help","doc":"Value is 'Metadata about an optical channel used to record from an imaging plane'","dtype":"text","value":"Metadata about an optical channel used to record from an imaging plane"}]}],"datasets":[{"dtype":"text","name":"description","doc":"Description of image_plane_X","quantity":"?"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength in nm"},{"dtype":"float","name":"imaging_rate","doc":"Rate images are acquired, in Hz."},{"dtype":"text","name":"indicator","doc":"Calcium indicator"},{"dtype":"text","name":"location","doc":"Location of image plane"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x|y|z"],["height","width","depth","x|y|z"]],"dtype":"float32","name":"manifold","doc":"Physical position of each pixel. COMMENT: 'xyz' represents the position of the pixel relative to the defined coordinate space","quantity":"?","attributes":[{"name":"conversion","doc":"Multiplier to get from stored values to specified unit (e.g., 1e-3 for millimeters)","required":false,"dtype":"float","default_value":1.0},{"name":"unit","doc":"Base unit that coordinates are stored in (e.g., Meters)","required":false,"dtype":"text","default_value":"Meter"}]},{"dtype":"text","name":"reference_frame","doc":"Describes position and reference frame of manifold based on position of first element in manifold. For example, text description of anatomical location or vectors needed to rotate to common anatomical axis (eg, AP/DV/ML). COMMENT: This field is necessary to interpret manifold. If manifold is not present then this field is not required","quantity":"?"}],"links":[{"name":"device","doc":"the device that was used to record from this electrode","target_type":"Device"}],"doc":"One of possibly many groups describing an imaging plane. COMMENT: Name is arbitrary but should be meaningful. It is referenced by TwoPhotonSeries and also ImageSegmentation and DfOverF interfaces","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane","attributes":[{"name":"help","doc":"Value is 'Metadata about an imaging plane'","dtype":"text","value":"Metadata about an imaging plane"}]},{"groups":[{"groups":[{"name":"corrected","doc":"Image stack with frames shifted to the common coordinates.","neurodata_type_inc":"ImageSeries"},{"name":"xy_translation","doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","neurodata_type_inc":"TimeSeries"}],"links":[{"name":"original","doc":"HDF5 Link to image series that is being registered.","target_type":"ImageSeries"}],"doc":"One of possibly many. Name should be informative.","quantity":"+","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack","attributes":[{"name":"help","doc":"Value is 'Reuslts from motion correction of an image stack'","dtype":"text","value":"Reuslts from motion correction of an image stack"}]}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection","attributes":[{"name":"help","doc":"Value is 'Image stacks whose frames have been shifted (registered) to account for motion'","dtype":"text","value":"Image stacks whose frames have been shifted (registered) to account for motion"}]}]}{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_phase_map","doc":"Phase response to stimulus on the first measured axis","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row|column"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_power_map","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_phase_map","doc":"Phase response to stimulus on the second measured axis","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_power_map","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null],"dims":["2"],"dtype":"text","name":"axis_descriptions","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta']"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"focal_depth_image","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"focal_depth","doc":"Focal depth offset, in meters","dtype":"float"},{"name":"format","doc":"Format of image. Right now only 'raw' supported","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"sign_map","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"vasculature_image","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"format","doc":"Format of image. Right now only 'raw' supported","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas.
Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy","attributes":[{"name":"help","doc":"Value is 'Intrinsic signal optical imaging or Widefield imaging for measuring retinotopy'","dtype":"text","value":"Intrinsic signal optical imaging or Widefield imaging for measuring retinotopy"}]}]}U{"namespaces":[{"doc":"NWB namespace","schema":[{"source":"nwb.base"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.0.2","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}x$././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.0.3_str_pub.nwb0000644000175100001730000043134014467767506020623 0ustar00runnerdockerHDF  2` TREEH:HEAP`H0 0 .speclocpHhTREEHEAPXPSNOD Hh(Pp P,H0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREE*HEAPX related_publications8 @help=<=0?#]GCOLone publication 2019-11-27T17:32:07.247036-08:00ADDMEADDME 2019-11-27T17:32:07.246039-08:00 2019-11-27T17:32:07.246039-08:00=an NWB:N file for storing cellular-based neurophysiology data2.0.2 core NWBFile  {"groups":[{"datasets":[{"dtype":"float","name":"start_time","doc":"Start time of epoch, in seconds","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'start time of the epoch, in seconds'","dtype":"text","value":"start time of the epoch, in seconds"}]},{"dtype":"float","name":"stop_time","doc":"Stop time of epoch, in seconds","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'stop time of the epoch, in seconds'","dtype":"text","value":"stop time of the epoch, in seconds"}]},{"dtype":"text","name":"tags","doc":"User-defined tags that identify events. Tags are to help identify or categorize events.","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'user-defined tags'","dtype":"text","value":"user-defined tags"}]},{"name":"tags_index","doc":"Index for tags","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries data[] field. COMMENT: This can be used to calculate location in TimeSeries timestamp[] field","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"name":"timeseries","doc":"An index into a TimeSeries object","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"name":"help","doc":"Value is 'Data on how an epoch applies to a time series'","dtype":"text","value":"Data on how an epoch applies to a time series"}]},{"name":"timeseries_index","doc":"Index for timeseries","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals","attributes":[{"name":"help","doc":"Value is 'A general epoch object'","dtype":"text","value":"A general epoch object"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}`SNOD2#]x2#]2#]2#]acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecifications3#]   *H  &{B{-{{5@V#8@VS {]1@V@VU@VSNODh-(  0 x(.8/p=0?8  1 H nwb_version H namespace Hneurodata_type PTREEhBHEAPXP?coreH?ATREEpFHEAPXB2.0.2HSNOD??ACETREEspQHEAP`ySNODCCE3#]GCOL8**{"datasets":[{"doc":"An abstract data type for a dataset","neurodata_type_def":"NWBData","attributes":[{"name":"help","doc":"Short description of what this type of Interface contains.","dtype":"text"}]},{"doc":"Pointers that index data values","neurodata_type_inc":"NWBData","neurodata_type_def":"Index","attributes":[{"name":"help","doc":"a help string","dtype":"text","value":"indexes into a list of values for a list of elements"},{"name":"target","doc":"the target dataset that this index applies to","dtype":{"target_type":"NWBData","reftype":"object"}}]},{"doc":"Data values indexed by pointer","neurodata_type_inc":"NWBData","neurodata_type_def":"VectorData","attributes":[{"name":"help","doc":"a help string","dtype":"text","value":"Values for a list of elements"},{"name":"description","doc":"A short description of what these vectors are","dtype":"text"}]},{"doc":"Pointers that index data values","neurodata_type_inc":"Index","neurodata_type_def":"VectorIndex","attributes":[{"name":"target","doc":"the target dataset that this index applies to","dtype":{"target_type":"VectorData","reftype":"object"}},{"name":"help","doc":"a help string","dtype":"text","value":"indexes into a list of values for a list of elements"}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"a unique identifier for each element","default_name":"element_id","neurodata_type_inc":"NWBData","neurodata_type_def":"ElementIdentifiers","attributes":[{"name":"help","doc":"a help string","dtype":"text","value":"unique identifiers for a list of elements"}]},{"dtype":"int","doc":"a region/index into a DynamicTable","neurodata_type_inc":"VectorData","neurodata_type_def":"DynamicTableRegion","attributes":[{"name":"help","doc":"value is 'a subset (i.e. slice or region) of a DynamicTable'","dtype":"text","value":"a subset (i.e. slice or region) of a DynamicTable"},{"name":"table","doc":"a reference to the DynamicTable this region applies to","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"name":"description","doc":"Description of what this table region points to","dtype":"text"}]},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["num_x","num_y"],["num_x","num_y","(r, g, b)"],["num_x","num_y","(r, g, b, a)"]],"doc":"Image base type.","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_def":"NWBContainer","attributes":[{"name":"help","doc":"Short description of what this type of NWBContainer contains.","dtype":"text"}]},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface","attributes":[{"name":"help","doc":"Short description of what this type of NWBContainer contains.","dtype":"text"}]},{"groups":[{"name":"sync","doc":"Lab specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. COMMENT: This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","quantity":"?"}],"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"uint8","name":"control","doc":"Numerical labels that apply to each element in data[]. COMMENT: Optional field. If present, the control array should have the same number of elements as data[].","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","name":"control_description","doc":"Description of each control value. COMMENT: Array length should be as long as the highest number in control minus one, generating an zero-based indexed array for control values.","quantity":"?"},{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"name":"data","doc":"Data values. Can also store binary data (eg, image frames) COMMENT: This field may be a link to data stored in an external file, especially in the case of raw data.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"dtype":"float64","name":"starting_time","doc":"The timestamp of the first sample. COMMENT: When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate.","quantity":"?","attributes":[{"name":"rate","doc":"Sampling rate, in Hz COMMENT: Rate information is stored in Hz","dtype":"float32"},{"name":"unit","doc":"Value is 'Seconds'","dtype":"text","value":"Seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data.COMMENT: Timestamps here have all been corrected to the common experiment master-clock. Time is stored as seconds and all timestamps are relative to experiment start time.","quantity":"?","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Value is 'Seconds'","dtype":"text","value":"Seconds"}]}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"},{"name":"help","doc":"Value is 'General time series object'","dtype":"text","value":"General time series object"}]},{"groups":[{"doc":"Interface objects containing data output from processing steps","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"doc":"Module. Name should be descriptive. Stores a collection of related data organized by contained interfaces. Each interface is a contract specifying content related to a particular type of data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"name":"description","doc":"Description of Module","dtype":"text"},{"name":"help","doc":"Value is 'A collection of analysis outputs from processing of data'","dtype":"text","value":"A collection of analysis outputs from processing of data"}]},{"datasets":[{"doc":"Images stored in this NWBDataInterface","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A NWBDataInterface for storing images that have some relationship","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"name":"description","doc":"Description of images in this container","dtype":"text"},{"name":"help","doc":"Value is 'A collection of images that have some meaningful relationship'","dtype":"text","value":"A collection of images that have some meaningful relationship"}]},{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"The unique identifier for the rows in this dynamic table","neurodata_type_inc":"ElementIdentifiers"},{"doc":"The vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"The indices for the vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorIndex"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). Apart from a column that contains unique identifiers for each row there are no other required datasets. Users are free to add any number of VectorData objects here. Table functionality is already supported through compound types, which is analogous to storing an array-of-structs. DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable. For example, DynamicTable was originally developed for storing trial data and spike unit metadata. Both of these use cases are expected to produce relatively small tables, so the spatial locality of multiple datasets present in a DynamicTable is not expected to have a significant performance impact. Additionally, requirements of trial and unit metadata tables are sufficiently diverse that performance implications can be overlooked in favor of usability.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DynamicTable","attributes":[{"name":"help","doc":"Value is 'A column-centric table'","dtype":"text","value":"A column-centric table"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}SNODTGXxh@NHt 3#]03#]@3#]P3#]`3#]nwb.basenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOL@&{"datasets":[{"shape":[null,null],"dims":["y","x"],"doc":"Grayscale image","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]},{"shape":[null,null,3],"dims":["y","x","R,G,B"],"doc":"Color image","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]},{"shape":[null,null,4],"dims":["y","x","R,G,B,A"],"doc":"Color image with transparency","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage","attributes":[{"name":"help","doc":"base image (use GrayscaleImage, RGBImage, RGBAImage, etc.)","dtype":"text"},{"name":"resolution","doc":"pixels / cm","required":false,"dtype":"float"},{"name":"description","doc":"description of image","required":false,"dtype":"text"}]}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","y","x"],["frame","z","y","x"]],"dtype":"numeric","name":"data","doc":"Either binary data containing image or empty.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","name":"dimension","doc":"Number of pixels on x, y, (and z) axes.","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","name":"external_file","doc":"Path or URL to one or more external file(s). Field only present if format=external. NOTE: this is only relevant if the image is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another HDF5 file and that file is HDF5 linked to this file.","quantity":"?","attributes":[{"name":"starting_frame","doc":"Each entry is the frame number (within the full ImageSeries) of the first frame in the corresponding external_file entry. This serves as an index to what frames each file contains, allowing random access.Zero-based indexing is used. (The first element will always be zero).","dtype":"int","shape":[null],"dims":["num_files"]}]},{"dtype":"text","name":"format","doc":"Format of image. If this is 'external' then the field external_file contains the path or URL information to that file. For tiff, png, jpg, etc, the binary representation of the image is stored in data. If the format is raw then the fields bit_per_pixel and dimension are used. For raw images, only a single channel is stored (eg, red).","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the HDF5 file in a raw format while other times it will be stored as an external image file in the host file system. The data field will either be binary data or empty. TimeSeries::data array structure: [frame] [y][x] or [frame][z][y][x].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries","attributes":[{"name":"help","doc":"Value is 'Storage object for time-series 2-D image data'","dtype":"text","value":"Storage object for time-series 2-D image data"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"links":[{"name":"masked_imageseries","doc":"Link to ImageSeries that mask is applied to.","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The data[] array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries","attributes":[{"name":"help","doc":"Value is 'An alpha mask that is applied to a presented visual stimulus'","dtype":"text","value":"An alpha mask that is applied to a presented visual stimulus"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"float32","name":"distance","doc":"Distance from camera/monitor to target/eye.","quantity":"?"},{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area (meters).","quantity":"?"},{"dtype":"text","name":"orientation","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (eg, how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries","attributes":[{"name":"help","doc":"Value is 'Time-series image stack for optical recording or stimulus'","dtype":"text","value":"Time-series image stack for optical recording or stimulus"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int","name":"data","doc":"Index of the frame in the referenced ImageSeries.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]}],"links":[{"name":"indexed_timeseries","doc":"HDF5 link to TimeSeries containing images that are indexed.","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries","attributes":[{"name":"help","doc":"Value is 'A sequence that is generated from an existing image stack. Frames can be presented in an arbitrary order. The data[] field stores frame number in reference stack'","dtype":"text","value":"A sequence that is generated from an existing image stack. Frames can be presented in an arbitrary order. The data[] field stores frame number in reference stack"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]}]}B{"groups":[{"groups":[{"groups":[{"doc":"Any objects representing acquired data","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"name":"acquisition","doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. COMMENT: This group is read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external HDF5 files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. MORE_INFO: Acquired data includes tracking and experimental data streams (ie, everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate HDF5 file that is linked to by the file being used for processing and analysis."},{"groups":[{"doc":"Custom analysis results","quantity":"*","neurodata_type_inc":"NWBContainer"}],"name":"analysis","doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. COMMENT: To facilitate sharing analysis data between labs, the contents here should be stored in standard types (eg, INCF types) and appropriately documented. MORE_INFO: The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs."},{"groups":[{"doc":"Intermediate analysis of acquired data","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"name":"processing","doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. COMMENT: Modules are defined below. They can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. MORE_INFO: 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis. These are performed using Modules, as defined above. All modules reside in the processing group."},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"presentation","doc":"Stimuli presented during the experiment."},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"templates","doc":"Template stimuli. COMMENT: Time stamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame."}],"name":"stimulus","doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus) COMMENT: This group is read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. MORE_INFO: Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be HDF5-linked to a remote library file."},{"groups":[{"doc":"place-holder than can be extended so that lab-specific meta-data can be placed in /general","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData","attributes":[{"name":"help","doc":"Short description of what this type of NWBContainer contains.","dtype":"text"}]},{"groups":[{"doc":"One of possibly many. Information about device and device description.","quantity":"+","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"name":"help","doc":"Value is 'A recording device e.g. amplifier'.","dtype":"text","value":"A recording device e.g. amplifier"}]}],"name":"devices","doc":"Description of hardware devices used during experiment. COMMENT: Eg, monitors, ADC boards, microscopes, etc","quantity":"?"},{"datasets":[{"dtype":"text","name":"age","doc":"Age of subject","quantity":"?"},{"dtype":"isodatetime","name":"date_of_birth","doc":"can be supplied instead of age","quantity":"?"},{"dtype":"text","name":"description","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","quantity":"?"},{"dtype":"text","name":"genotype","doc":"Genetic strain COMMENT: If absent, assume Wild Type (WT)","quantity":"?"},{"dtype":"text","name":"sex","doc":"Gender of subject","quantity":"?"},{"dtype":"text","name":"species","doc":"Species of subject","quantity":"?"},{"dtype":"text","name":"subject_id","doc":"ID of animal/person used/participating in experiment (lab convention)","quantity":"?"},{"dtype":"text","name":"weight","doc":"Weight at time of experiment, at time of surgery and at other important times","quantity":"?"}],"name":"subject","doc":"Information about the animal or person from which the data was measured.","quantity":"?","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject","attributes":[{"name":"help","doc":"Value is 'Information about the subject'","dtype":"text","value":"Information about the subject"}]},{"groups":[{"doc":"One of possibly many groups, one for each electrode group.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float","name":"x","doc":"the x coordinate of the channel location","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the x coordinate of the channel location'","dtype":"text","value":"the x coordinate of the channel location"}]},{"dtype":"float","name":"y","doc":"the y coordinate of the channel location","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the y coordinate of the channel location'","dtype":"text","value":"the y coordinate of the channel location"}]},{"dtype":"float","name":"z","doc":"the z coordinate of the channel location","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the z coordinate of the channel location'","dtype":"text","value":"the z coordinate of the channel location"}]},{"dtype":"float","name":"imp","doc":"the impedance of the channel","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the impedance of the channel'","dtype":"text","value":"the impedance of the channel"}]},{"dtype":"ascii","name":"location","doc":"the location of channel within the subject e.g. brain region","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the location of channel within the subject e.g. brain region'","dtype":"text","value":"the location of channel within the subject e.g. brain region"}]},{"dtype":"float","name":"filtering","doc":"description of hardware filtering","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'description of hardware filtering'","dtype":"text","value":"description of hardware filtering"}]},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"group","doc":"a reference to the ElectrodeGroup this electrode is a part of","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'a reference to the ElectrodeGroup this electrode is a part of'","dtype":"text","value":"a reference to the ElectrodeGroup this electrode is a part of"}]},{"dtype":"ascii","name":"group_name","doc":"name of the ElectrodeGroup this electrode is a part of","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the name of the ElectrodeGroup this electrode is a part of'","dtype":"text","value":"the name of the ElectrodeGroup this electrode is a part of"}]}],"name":"electrodes","doc":"A table of all electrodes (i.e. channels) used for recording.","quantity":"?","neurodata_type_inc":"DynamicTable"}],"name":"extracellular_ephys","doc":"Metadata related to extracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"One of possibly many. COMMENT: Name should be informative.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"name":"sweep_table","doc":"The table which groups different PatchClampSeries together.","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","name":"filtering","doc":"Description of filtering used. COMMENT: Includes filtering type and parameters, frequency fall- off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","quantity":"?"}],"name":"intracellular_ephys","doc":"Metadata related to intracellular electrophysiology","quantity":"?"},{"groups":[{"doc":"One of possibly many groups describing an optogenetic stimulation site. COMMENT: Name is arbitrary but should be meaningful. Name is referenced by OptogeneticSeries.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"name":"optogenetics","doc":"Metadata describing optogenetic stimuluation","quantity":"?"},{"groups":[{"doc":"One of possibly many groups describing an imaging plane. COMMENT: Name is arbitrary but should be meaningful. It is referenced by TwoPhotonSeries and also ImageSegmentation and DfOverF interfaces.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"name":"optophysiology","doc":"Metadata related to optophysiology.","quantity":"?"}],"datasets":[{"dtype":"text","name":"data_collection","doc":"Notes about data collection and analysis.COMMENT: Can be from Methods","quantity":"?"},{"dtype":"text","name":"experiment_description","doc":"General description of the experiment.COMMENT: Can be from Methods","quantity":"?"},{"dtype":"text","name":"experimenter","doc":"Name of person who performed the experiment.COMMENT: More than one person OK. Can specify roles of different people involved.","quantity":"?"},{"dtype":"text","name":"institution","doc":"Institution(s) where experiment was performed","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","name":"keywords","doc":"Terms to search over","quantity":"?"},{"dtype":"text","name":"lab","doc":"Lab where experiment was performed","quantity":"?"},{"dtype":"text","name":"notes","doc":"Notes about the experiment. COMMENT: Things particular to this experiment","quantity":"?"},{"dtype":"text","name":"pharmacology","doc":"Description of drugs used, including how and when they were administered. COMMENT: Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","quantity":"?"},{"dtype":"text","name":"protocol","doc":"Experimental protocol, if applicable. COMMENT: E.g., include IACUC protocol.","quantity":"?"},{"dtype":"text","name":"related_publications","doc":"Publication information. COMMENT: PMID, DOI, URL, etc. If multiple, concatenate together and describe which is which. such as PMID, DOI, URL, etc","quantity":"?"},{"dtype":"text","name":"session_id","doc":"Lab-specific ID for the session.COMMENT: Only 1 session_id per file, with all time aligned to experiment start time.","quantity":"?"},{"dtype":"text","name":"slices","doc":"Description of slices, including information about preparation thickness, orientation, temperature and bath solution","quantity":"?"},{"dtype":"text","name":"source_script","doc":"Script file used to create this NWB file.","quantity":"?","attributes":[{"name":"file_name","doc":"Name of script file","dtype":"text"}]},{"dtype":"text","name":"stimulus","doc":"Notes about stimuli, such as how and where presented. COMMENT: Can be from Methods.","quantity":"?"},{"dtype":"text","name":"surgery","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery. COMMENT: Much can be copied from Methods.","quantity":"?"},{"dtype":"text","name":"virus","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","quantity":"?"}],"name":"general","doc":"Experimental metadata, including protocol, notes and description of hardware device(s). COMMENT: The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. MORE_INFO: General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them."},{"groups":[{"name":"epochs","doc":"divisions in time marking experimental stages or sub-divisions of a single recording session","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"trials","doc":"repeated experimental events that have a logical grouping","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"invalid_times","doc":"time intervals that should be removed from analysis","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"an optional additional table for describing other experimental time intervals","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"name":"intervals","doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","quantity":"?"},{"name":"units","doc":"Data about units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","name":"file_create_date","doc":"A record of the date the file was created and of subsequent modifications. COMMENT: - The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00 - Dates stored in UTC end in \"Z\" with no timezone offset. - Date accuracy is up to milliseconds. - The file can be created after the experiment was run, so this may differ from the experiment start time. - Each modification to the nwb file adds a new entry to the array."},{"dtype":"text","name":"identifier","doc":"A unique text identifier for the file. COMMENT: Eg, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files."},{"dtype":"text","name":"session_description","doc":"One or two sentences describing the experiment and data in the file."},{"dtype":"isodatetime","name":"session_start_time","doc":"Date and time of the experiment/session start. COMMENT: - The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00 - Dates stored in UTC end in \"Z\" with no timezone offset. - Date accuracy is up to milliseconds."},{"dtype":"isodatetime","name":"timestamps_reference_time","doc":"Date and time corresponding to time zero of all timestamps. COMMENT: - The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00 - Dates stored in UTC end in \"Z\" with no timezone offset. - Date accuracy is up to milliseconds. - All times stored in the file use this time as reference (ie, time zero)."}],"name":"root","doc":"Top level of NWB file.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"name":"help","doc":"Value is 'an NWB:N file for storing cellular-based neurophysiology data'","dtype":"text","value":"an NWB:N file for storing cellular-based neurophysiology data"},{"name":"nwb_version","doc":"File version string. COMMENT: Eg, NWB-1.0.0. This will be the name of the format with trailing major, minor and patch numbers.","dtype":"text","value":"2.0.2"}]}]}-{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"Values of each feature at each time.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"feature_units","doc":"Units of each feature.","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"features","doc":"Description of the features represented in TimeSeries::data."}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries","attributes":[{"name":"help","doc":"Value is 'Features of an applied stimulus. This is useful when storing the raw stimulus is impractical'","dtype":"text","value":"Features of an applied stimulus. This is useful when storing the raw stimulus is impractical"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","name":"data","doc":"Annotations made during an experiment.","attributes":[{"name":"resolution","doc":"Value is -1.0","dtype":"float","value":-1.0},{"name":"unit","doc":"Value is 'n/a'","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores, eg, user annotations made during an experiment. The TimeSeries::data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries","attributes":[{"name":"help","doc":"Value is 'Time-stamped annotations about an experiment'","dtype":"text","value":"Time-stamped annotations about an experiment"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","name":"data","doc":">0 if interval started, <0 if interval ended.","attributes":[{"name":"resolution","doc":"Value is -1.0","dtype":"float","value":-1.0},{"name":"unit","doc":"Value is 'n/a'","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries","attributes":[{"name":"help","doc":"Value is 'Stores the start and stop times for events'","dtype":"text","value":"Stores the start and stop times for events"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"groups":[{"datasets":[{"dtype":"text","name":"band_name","doc":"the name of the band e.g. theta","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'the name of the band e.g. theta'","dtype":"text","value":"the name of the band e.g. theta"}]},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float","name":"band_limits","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center'","dtype":"text","value":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center"}]},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_mean","doc":"The mean Gaussian filters in Hz","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"The mean Gaussian filters in Hz","dtype":"text","value":"The mean Gaussian filters in Hz"}]},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_stdev","doc":"The standard devaition of Gaussian filters in Hz","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"The standard devaition of Gaussian filters in Hz","dtype":"text","value":"The standard devaition of Gaussian filters in Hz"}]}],"name":"bands","doc":"A table for describing the bands that this series was generated from. There should be one row in this table for each band","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","name":"data","doc":"The data goes here","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"dtype":"text","name":"metric","doc":"recommended: phase, amplitude, power"}],"links":[{"name":"source_timeseries","doc":"HDF5 link to TimesSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here","target_type":"TimeSeries","quantity":"?"}],"doc":"Holds spectral analysis of a timeseries. For instance of LFP or a speech signal","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries","attributes":[{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"},{"name":"help","doc":"Value is 'General time series object'","dtype":"text","value":"General time series object"}]},{"datasets":[{"name":"spike_times_index","doc":"the index into the spike_times dataset","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"double","name":"spike_times","doc":"the spike times for each unit","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"obs_intervals_index","doc":"the index into the obs_intervals dataset","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"double","name":"obs_intervals","doc":"the observation intervals for each unit","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"electrodes_index","doc":"the index into electrodes","quantity":"?","neurodata_type_inc":"VectorIndex"},{"name":"electrodes","doc":"the electrode that each spike unit came from","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"electrode_group","doc":"the electrode group that each spike unit came from","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_mean","doc":"the spike waveform mean for each spike unit","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_sd","doc":"the spike waveform standard deviation for each spike unit","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units","attributes":[{"name":"help","doc":"Value is 'Data about spiking units'","dtype":"text","value":"Data about spiking units"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"2-D array storing position or direction relative to some reference frame.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"meter"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"dtype":"text","name":"reference_frame","doc":"Description defining what exactly 'straight-ahead' means.","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries","attributes":[{"name":"help","doc":"Value is: Stores points in space over time. The data[] array structure is [num samples][num spatial dimensions]","dtype":"text","value":"Stores points in space over time. The data[] array structure is [num samples][num spatial dimensions]"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs","attributes":[{"name":"help","doc":"Value is 'General container for storing behavioral epochs'","dtype":"text","value":"General container for storing behavioral epochs"}]},{"groups":[{"doc":"TimeSeries object containing irregular behavioral events","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents","attributes":[{"name":"help","doc":"Value is 'Position data, whether along the x, xy or xyz axis'","dtype":"text","value":"Position data, whether along the x, xy or xyz axis"}]},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data.See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries","attributes":[{"name":"help","doc":"Value is 'General container for storing continuously sampled behavioral data.'","dtype":"text","value":"General container for storing continuously sampled behavioral data."}]},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking","attributes":[{"name":"help","doc":"Value is 'Eye-tracking data, representing pupil size'","dtype":"text","value":"Eye-tracking data, representing pupil size"}]},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking","attributes":[{"name":"help","doc":"Value is 'Eye-tracking data, representing direction of gaze'","dtype":"text","value":"Eye-tracking data, representing direction of gaze"}]},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection","attributes":[{"name":"help","doc":"Value is 'Direction as measured radially. Spatial series reference frame should indicate which direction corresponds to zero and what is the direction of positive rotation'","dtype":"text","value":"Direction as measured radially. Spatial series reference frame should indicate which direction corresponds to zero and what is the direction of positive rotation"}]},{"groups":[{"doc":"SpatialSeries object containing position data","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position","attributes":[{"name":"help","doc":"Value is 'Position data, whether along the x, xy or xyz axis'","dtype":"text","value":"Position data, whether along the x, xy or xyz axis"}]}]}S {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Applied power for optogenetic stimulus.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"watt"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]}],"links":[{"name":"site","doc":"link to OptogeneticStimulusSite group that describes the site to which this stimulus was applied","target_type":"OptogeneticStimulusSite"}],"doc":"Optogenetic stimulus. The data[] field is in unit of watts.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries","attributes":[{"name":"help","doc":"Value is 'Optogenetic stimulus'","dtype":"text","value":"Optogenetic stimulus"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of site"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength in nm"},{"dtype":"text","name":"location","doc":"Location of stimulation site"}],"links":[{"name":"device","doc":"Device that generated the stimulus","target_type":"Device"}],"doc":"One of possibly many groups describing an optogenetic stimulation site. COMMENT: Name is arbitrary but should be meaningful. Name is referenced by OptogeneticSeries","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite","attributes":[{"name":"help","doc":"Value is 'Metadata about an optogenetic stimulus site'","dtype":"text","value":"Metadata about an optogenetic stimulus site"}]}]}p3#]3#]3#]SNOD8hvxPO(XuHxw`PRS3#]3#]3#]GCOL5{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Recorded voltage data.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"volt"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"name":"electrodes","doc":"the electrodes that this series was generated from","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Stores acquired voltage data from extracellular recordings. The data field of an ElectricalSeries is an int or float array storing data in Volts. TimeSeries::data array structure: :blue:`[num times] [num channels] (or [num_times] for single electrode).`","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"name":"help","doc":"Value is 'Stores acquired voltage data from extracellular recordings'","dtype":"text","value":"Stores acquired voltage data from extracellular recordings"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Spike waveforms.","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"volt"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data.COMMENT: Timestamps here have all been corrected to the common experiment master-clock. Time is stored as seconds and all timestamps are relative to experiment start time. This is added here so that the timestamps is required for SpikeEventTimes.","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Value is 'Seconds'","dtype":"text","value":"Seconds"}]}],"doc":"Stores 'snapshots' of spike events (i.e., threshold crossings) in data. This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describing how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries","attributes":[{"name":"help","doc":"Value is 'Snapshots of spike events from data.'","dtype":"text","value":"Snapshots of spike events from data."},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"text","name":"waveform_filtering","doc":"Filtering applied to data before generating mean/sd"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_mean","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_sd","doc":"Stdev of waveforms for each cluster, using the same indices as in mean"}],"links":[{"name":"clustering_interface","doc":"HDF5 link to Clustering interface that was the source of the clustered data","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms","attributes":[{"name":"help","doc":"Value is 'Mean waveform shape of clusters. Waveforms should be high-pass filtered (ie, not the same bandpass filter used waveform analysis and clustering)'","dtype":"text","value":"DEPRECATED Mean waveform shape of clusters. Waveforms should be high-pass filtered (ie, not the same bandpass filter used waveform analysis and clustering)"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)"},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"num","doc":"Cluster number of each event"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","name":"peak_over_rms","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric)."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module."}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering","attributes":[{"name":"help","doc":"Value is 'Clustered spike data, whether from automatic clustering tools (eg, klustakwik) or as a result of manual sorting'","dtype":"text","value":"DEPRECATED Clustered spike data, whether from automatic clustering tools (eg, klustakwik) or as a result of manual sorting"}]},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","name":"description","doc":"Description of features (eg, ''PC1'') for each of the extracted features."},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","name":"features","doc":"Multi-dimensional array of features extracted from each event."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of events that features correspond to (can be a link)."},{"name":"electrodes","doc":"the electrodes that this series was generated from","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEvent TimeSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction","attributes":[{"name":"help","doc":"Value is 'Container for salient features of detected events'","dtype":"text","value":"Container for salient features of detected events"}]},{"datasets":[{"dtype":"text","name":"detection_method","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values."},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"source_idx","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. Module description should define what is meant by time of event (e.g., .25msec before action potential peak, zero-crossing time, etc). The index points to each event from the raw data"},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Timestamps of events, in Seconds","attributes":[{"name":"unit","doc":"The string ''Seconds''","required":false,"dtype":"text","default_value":"Seconds"}]}],"links":[{"name":"source_electricalseries","doc":"HDF5 link to ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to mandate that information be stored here","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection","attributes":[{"name":"help","doc":"Value is 'Detected spike events from voltage trace(s)'","dtype":"text","value":"Detected spike events from voltage trace(s)"}]},{"groups":[{"doc":"SpikeEventSeries object containing detected spike event waveforms","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform","attributes":[{"name":"help","doc":"Value is 'Waveform of detected extracellularly recorded spike events'","dtype":"text","value":"Waveform of detected extracellularly recorded spike events"}]},{"groups":[{"doc":"ElectricalSeries object containing filtered electrophysiology data","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Ephys data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys","attributes":[{"name":"help","doc":"Value is 'Ephys data from one or more channels that is subjected to filtering, such as for gamma or theta oscillations (LFP has its own interface). Filter properties should be noted in the ElectricalSeries'","dtype":"text","value":"Ephys data from one or more channels that is subjected to filtering, such as for gamma or theta oscillations (LFP has its own interface). Filter properties should be noted in the ElectricalSeries"}]},{"groups":[{"doc":"ElectricalSeries object containing LFP data for one or more channels","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries description or comments field.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP","attributes":[{"name":"help","doc":"Value is 'LFP data from one or more channels. Filter properties should be noted in the ElectricalSeries'","dtype":"text","value":"LFP data from one or more channels. Filter properties should be noted in the ElectricalSeries"}]},{"links":[{"name":"device","doc":"the device that was used to record from this electrode group","target_type":"Device","quantity":"?"}],"doc":"One of possibly many groups, one for each electrode group.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"name":"help","doc":"Value is 'Metadata about a physical grouping of channels'","dtype":"text","value":"A physical grouping of channels"},{"name":"description","doc":"description of this electrode group","dtype":"text"},{"name":"location","doc":"description of location of this electrode group","dtype":"text"}]}]}#8{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Recorded voltage or current.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"dtype":"float","name":"gain","doc":"Units: Volt/Amp (v-clamp) or Volt/Volt (c-clamp)","quantity":"?"}],"links":[{"name":"electrode","doc":"link to IntracellularElectrode group that describes th electrode that was used to apply or record this data","target_type":"IntracellularElectrode"}],"doc":"Stores stimulus or response current or voltage. Superclass definition for patch-clamp data (this class should not be instantiated directly).","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"name":"help","doc":"Value is 'Superclass definition for patch-clamp data'","dtype":"text","value":"Superclass definition for patch-clamp data"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"float32","name":"bias_current","doc":"Unit: Amp","quantity":"?"},{"dtype":"float32","name":"bridge_balance","doc":"Unit: Ohm","quantity":"?"},{"dtype":"float32","name":"capacitance_compensation","doc":"Unit: Farad","quantity":"?"}],"doc":"Stores voltage data recorded from intracellular current-clamp recordings. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries","attributes":[{"name":"help","doc":"Value is 'Voltage recorded from cell during current-clamp recording'","dtype":"text","value":"Voltage recorded from cell during current-clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"doc":"Stores recorded voltage data from intracellular recordings when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"name":"help","doc":"Value is 'Voltage from intracellular recordings when all current and amplifier settings are off'","dtype":"text","value":"Voltage from intracellular recordings when all current and amplifier settings are off"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"doc":"Aliases to standard PatchClampSeries. Its functionality is to better tag PatchClampSeries for machine (and human) readability of the file.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries","attributes":[{"name":"help","doc":"Value is 'Stimulus current applied during current clamp recording'","dtype":"text","value":"Stimulus current applied during current clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"float32","name":"capacitance_fast","doc":"Unit: Farad","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Farad"}]},{"dtype":"float32","name":"capacitance_slow","doc":"Unit: Farad","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Farad"}]},{"dtype":"float32","name":"resistance_comp_bandwidth","doc":"Unit: Hz","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Hz"}]},{"dtype":"float32","name":"resistance_comp_correction","doc":"Unit: %","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"percent"}]},{"dtype":"float32","name":"resistance_comp_prediction","doc":"Unit: %","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"percent"}]},{"dtype":"float32","name":"whole_cell_capacitance_comp","doc":"Unit: Farad","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Farad"}]},{"dtype":"float32","name":"whole_cell_series_resistance_comp","doc":"Unit: Ohm","quantity":"?","attributes":[{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","required":false,"dtype":"text","default_value":"Ohm"}]}],"doc":"Stores current data recorded from intracellular voltage-clamp recordings. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries","attributes":[{"name":"help","doc":"Value is 'Current recorded from cell during voltage-clamp recording'","dtype":"text","value":"Current recorded from cell during voltage-clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"doc":"Aliases to standard PatchClampSeries. Its functionality is to better tag PatchClampSeries for machine (and human) readability of the file.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries","attributes":[{"name":"help","doc":"Value is 'Stimulus voltage applied during voltage clamp recording'","dtype":"text","value":"Stimulus voltage applied during voltage clamp recording"},{"name":"stimulus_description","doc":"the protocol/stimulus name for this patch-clamp dataset","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Recording description, description of electrode (e.g., whole-cell, sharp, etc)COMMENT: Free-form text (can be from Methods)"},{"dtype":"text","name":"filtering","doc":"Electrode specific filtering.","quantity":"?"},{"dtype":"text","name":"initial_access_resistance","doc":"Initial access resistance","quantity":"?"},{"dtype":"text","name":"location","doc":"Area, layer, comments on estimation, stereotaxis coordinates (if in vivo, etc)","quantity":"?"},{"dtype":"text","name":"resistance","doc":"Electrode resistance COMMENT: unit: Ohm","quantity":"?"},{"dtype":"text","name":"seal","doc":"Information about seal used for recording","quantity":"?"},{"dtype":"text","name":"slice","doc":"Information about slice used for recording","quantity":"?"}],"links":[{"name":"device","doc":"the device that was used to record from this electrode","target_type":"Device"}],"doc":"One of possibly many. COMMENT: Name should be informative.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode","attributes":[{"name":"help","doc":"Value is 'Metadata about an intracellular electrode'","dtype":"text","value":"Metadata about an intracellular electrode"}]},{"datasets":[{"dtype":"uint64","name":"sweep_number","doc":"The sweep number of the PatchClampSeries in that row.","neurodata_type_inc":"VectorData","attributes":[{"name":"description","doc":"value is 'The sweep number of the PatchClampSeries in that row'","dtype":"text","value":"The sweep number of the PatchClampSeries in that row"}]},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"name":"series","doc":"The PatchClampSeries with the sweep number in that row","neurodata_type_inc":"VectorData","attributes":[{"name":"help","doc":"Value is 'The PatchClampSeries with the sweep number in that row'","dtype":"text","value":"The PatchClampSeries with the sweep number in that row"}]},{"name":"series_index","doc":"Index for series","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable","attributes":[{"name":"help","doc":"Value is 'The table which groups different PatchClampSeries together'","dtype":"text","value":"The table which groups different PatchClampSeries together"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}]}]1{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":["width|height","width|height|depth"],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area (meters).","quantity":"?"}],"links":[{"name":"imaging_plane","doc":"link to ImagingPlane group from which this TimeSeries data was generated","target_type":"ImagingPlane"}],"doc":"A special case of optical imaging.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"name":"help","doc":"Value is 'Image stack recorded from 2-photon microscope'","dtype":"text","value":"Image stack recorded from 2-photon microscope"},{"name":"pmt_gain","doc":"Photomultiplier gain","required":false,"dtype":"float32"},{"name":"scan_line_rate","doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","required":false,"dtype":"float32"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","name":"data","doc":"Signals from ROIs","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified unit","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit. COMMENT: E.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0","required":false,"dtype":"float32","default_value":0.0},{"name":"unit","doc":"The base unit of measure used to store data. This should be in the SI unit. COMMENT: This is the SI unit (when appropriate) of the stored data, such as Volts. If the actual data is stored in millivolts, the field 'conversion' below describes how to convert the data to the specified SI unit.","dtype":"text"}]},{"name":"rois","doc":"a dataset referencing into an ROITable containing information on the ROIs stored in this timeseries","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. Each row in data[] should correspond to the signal from one ROI.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries","attributes":[{"name":"help","doc":"Value is 'ROI responses over an imaging plane. Each element on the second dimension of data[] should correspond to the signal from one ROI'","dtype":"text","value":"ROI responses over an imaging plane. Each element on the second dimension of data[] should correspond to the signal from one ROI"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"},{"name":"description","doc":"Description of TimeSeries","required":false,"dtype":"text","default_value":"no description"}]},{"groups":[{"doc":"RoiResponseSeries object containing dF/F for a ROI","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF","attributes":[{"name":"help","doc":"Value is 'Df/f over time of one or more ROIs. TimeSeries names should correspond to imaging plane names'","dtype":"text","value":"Df/f over time of one or more ROIs. TimeSeries names should correspond to imaging plane names"}]},{"groups":[{"doc":"RoiResponseSeries object containing fluorescence data for a ROI","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence","attributes":[{"name":"help","doc":"Value is 'Fluorescence over time of one or more ROIs. TimeSeries names should correspond to imaging plane names'","dtype":"text","value":"Fluorescence over time of one or more ROIs. TimeSeries names should correspond to imaging plane names"}]},{"groups":[{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack)","quantity":"*","neurodata_type_inc":"ImageSeries"}],"name":"reference_images","doc":"Stores image stacks segmentation mask apply to."}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"name":"image_mask","doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"pixel_mask_index","doc":"index into pixel_mask","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"the pixel x-coordinate","name":"x","dtype":"uint"},{"doc":"the pixel y-coordinate","name":"y","dtype":"uint"},{"doc":"the weight of the pixel","name":"weight","dtype":"float"}],"name":"pixel_mask","doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"voxel_mask_index","doc":"index into voxel_mask","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"the voxel x-coordinate","name":"x","dtype":"uint"},{"doc":"the voxel y-coordinate","name":"y","dtype":"uint"},{"doc":"the voxel y-coordinate","name":"z","dtype":"uint"},{"doc":"the weight of the voxel","name":"weight","dtype":"float"}],"name":"voxel_mask","doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"The unique identifier for the rows in this dynamic table","neurodata_type_inc":"ElementIdentifiers"},{"doc":"The vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"The indices for the vector columns in this dynamic table","quantity":"*","neurodata_type_inc":"VectorIndex"}],"links":[{"name":"imaging_plane","doc":"link to ImagingPlane group from which this TimeSeries data was generated","target_type":"ImagingPlane"}],"doc":"results for image segmentation of a specific imaging plane","quantity":"+","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation","attributes":[{"name":"help","doc":"Value is 'Results from segmentation of an imaging plane'","dtype":"text","value":"Results from segmentation of an imaging plane"},{"name":"colnames","doc":"The names of the columns in this table. This should be used to specifying an order to the columns","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table","dtype":"text"}]}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation","attributes":[{"name":"help","doc":"Value is 'Stores groups of pixels that define regions of interest from one or more imaging planes'","dtype":"text","value":"Stores groups of pixels that define regions of interest from one or more imaging planes"}]},{"groups":[{"datasets":[{"dtype":"text","name":"description","doc":"Any notes or comments about the channel"},{"dtype":"float","name":"emission_lambda","doc":"Emission wavelength for channel in nm"}],"doc":"One of possibly many groups storing channel-specific data COMMENT: Name is arbitrary but should be meaningful","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel","attributes":[{"name":"help","doc":"Value is 'Metadata about an optical channel used to record from an imaging plane'","dtype":"text","value":"Metadata about an optical channel used to record from an imaging plane"}]}],"datasets":[{"dtype":"text","name":"description","doc":"Description of image_plane_X","quantity":"?"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength in nm"},{"dtype":"float","name":"imaging_rate","doc":"Rate images are acquired, in Hz."},{"dtype":"text","name":"indicator","doc":"Calcium indicator"},{"dtype":"text","name":"location","doc":"Location of image plane"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x|y|z"],["height","width","depth","x|y|z"]],"dtype":"float32","name":"manifold","doc":"Physical position of each pixel. COMMENT: 'xyz' represents the position of the pixel relative to the defined coordinate space","quantity":"?","attributes":[{"name":"conversion","doc":"Multiplier to get from stored values to specified unit (e.g., 1e-3 for millimeters)","required":false,"dtype":"float","default_value":1.0},{"name":"unit","doc":"Base unit that coordinates are stored in (e.g., Meters)","required":false,"dtype":"text","default_value":"Meter"}]},{"dtype":"text","name":"reference_frame","doc":"Describes position and reference frame of manifold based on position of first element in manifold. For example, text description of anatomical location or vectors needed to rotate to common anatomical axis (eg, AP/DV/ML). COMMENT: This field is necessary to interpret manifold. If manifold is not present then this field is not required","quantity":"?"}],"links":[{"name":"device","doc":"the device that was used to record from this electrode","target_type":"Device"}],"doc":"One of possibly many groups describing an imaging plane. COMMENT: Name is arbitrary but should be meaningful. It is referenced by TwoPhotonSeries and also ImageSegmentation and DfOverF interfaces","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane","attributes":[{"name":"help","doc":"Value is 'Metadata about an imaging plane'","dtype":"text","value":"Metadata about an imaging plane"}]},{"groups":[{"groups":[{"name":"corrected","doc":"Image stack with frames shifted to the common coordinates.","neurodata_type_inc":"ImageSeries"},{"name":"xy_translation","doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","neurodata_type_inc":"TimeSeries"}],"links":[{"name":"original","doc":"HDF5 Link to image series that is being registered.","target_type":"ImageSeries"}],"doc":"One of possibly many. Name should be informative.","quantity":"+","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack","attributes":[{"name":"help","doc":"Value is 'Reuslts from motion correction of an image stack'","dtype":"text","value":"Reuslts from motion correction of an image stack"}]}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection","attributes":[{"name":"help","doc":"Value is 'Image stacks whose frames have been shifted (registered) to account for motion'","dtype":"text","value":"Image stacks whose frames have been shifted (registered) to account for motion"}]}]}{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_phase_map","doc":"Phase response to stimulus on the first measured axis","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row|column"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_power_map","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_phase_map","doc":"Phase response to stimulus on the second measured axis","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_power_map","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees)","dtype":"text"}]},{"shape":[null],"dims":["2"],"dtype":"text","name":"axis_descriptions","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta']"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"focal_depth_image","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"focal_depth","doc":"Focal depth offset, in meters","dtype":"float"},{"name":"format","doc":"Format of image. Right now only 'raw' supported","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"sign_map","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"vasculature_image","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"format","doc":"Format of image. Right now only 'raw' supported","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas.
Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy","attributes":[{"name":"help","doc":"Value is 'Intrinsic signal optical imaging or Widefield imaging for measuring retinotopy'","dtype":"text","value":"Intrinsic signal optical imaging or Widefield imaging for measuring retinotopy"}]}]}U{"namespaces":[{"doc":"NWB namespace","schema":[{"source":"nwb.base"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.0.2","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}x$././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.1.0_nwbfile.nwb0000644000175100001730000042626014467767506020576 0ustar00runnerdockerHDF  ,` TREEHP/HEAP`- 0 .speclocpHhTREEHEAPXPSNOD Hh(Pp PH0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREEHEAPXP H nwb_version1:<#]x GCOL 2019-11-27T17:32:32.461235-08:00ADDMEADDME 2019-11-27T17:32:32.460239-08:00 2019-11-27T17:32:32.460239-08:002.1.0coreNWBFile $35ee1e61-e948-479d-9a14-8ed8cbedd9f5 G{"groups":[{"datasets":[{"dtype":"float","name":"start_time","doc":"Start time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"stop_time","doc":"Stop time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"text","name":"tags","doc":"User-defined tags that identify or categorize events.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"tags_index","doc":"Index for tags.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to.","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"name":"timeseries","doc":"An index into a TimeSeries object.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"timeseries_index","doc":"Index for timeseries.","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}X2#]2#]2#]acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh*(  0 x+,p:<8  02#] H namespace Hneurodata_type H object_id$ P  S'xFG y(u:u,1uu0@EB@E~ u,@E@EU@ETREE@HEAPX=coreH=?TREE DHEAPX?2.1.0HSNODX==?ACTREEmp@HEAP`tSNOD`AAC3#]GCOLx'S'{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_def":"NWBData"},{"doc":"Pointers that index data values.","neurodata_type_inc":"NWBData","neurodata_type_def":"Index","attributes":[{"name":"target","doc":"Target dataset that this index applies to.","dtype":{"target_type":"NWBData","reftype":"object"}}]},{"doc":"A 1-dimensional dataset. This can be indexed using a VectorIndex to encode a 2-dimensional ragged array in 1 dimension. The first vector is at VectorData[0:VectorIndex(0)+1]. The second vector is at VectorData[VectorIndex(0)+1:VectorIndex(1)+1]. And so on.","neurodata_type_inc":"NWBData","neurodata_type_def":"VectorData","attributes":[{"name":"description","doc":"Description of what these vectors represent.","dtype":"text"}]},{"doc":"An array of indices into the first dimension of the target VectorData. Can be used with VectorData to encode a 2-dimensional ragged array in 1 dimension.","neurodata_type_inc":"Index","neurodata_type_def":"VectorIndex","attributes":[{"name":"target","doc":"Reference to the target dataset that this index applies to.","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","neurodata_type_inc":"NWBData","neurodata_type_def":"ElementIdentifiers"},{"dtype":"int","doc":"A region/index into a DynamicTable.","neurodata_type_inc":"VectorData","neurodata_type_def":"DynamicTableRegion","attributes":[{"name":"table","doc":"Reference to the DynamicTable object that this region applies to.","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"name":"description","doc":"Description of what this table region points to.","dtype":"text"}]},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["num_x","num_y"],["num_x","num_y","(r, g, b)"],["num_x","num_y","(r, g, b, a)"]],"doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"name":"sync","doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"name":"data","doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"dtype":"float64","name":"starting_time","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","quantity":"?","attributes":[{"name":"rate","doc":"Sampling rate, in Hz.","dtype":"float32"},{"name":"unit","doc":"Unit of measurement for time, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","quantity":"?","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","name":"control","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","name":"control_description","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"name":"description","doc":"Description of this collection of processed data.","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A collection of images.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"name":"description","doc":"Description of this collection of images.","dtype":"text"}]},{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","neurodata_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorIndex"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). Apart from a column that contains unique identifiers for each row there are no other required datasets. Users are free to add any number of VectorData objects here. Table functionality is already supported through compound types, which is analogous to storing an array-of-structs. DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable. For example, DynamicTable was originally developed for storing trial data and spike unit metadata. Both of these use cases are expected to produce relatively small tables, so the spatial locality of multiple datasets present in a DynamicTable is not expected to have a significant performance impact. Additionally, requirements of trial and unit metadata tables are sufficiently diverse that performance implications can be overlooked in favor of usability.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DynamicTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}SNODChEXxsh@=8o3#] 3#]03#]@3#]P3#]nwb.basenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOLPy({"datasets":[{"shape":[null,null],"dims":["y","x"],"doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,3],"dims":["y","x","R, G, B"],"doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,4],"dims":["y","x","R, G, B, A"],"doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","y","x"],["frame","z","y","x"]],"dtype":"numeric","name":"data","doc":"Binary data representing images across frames.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","name":"dimension","doc":"Number of pixels on x, y, (and z) axes.","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","name":"external_file","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","quantity":"?","attributes":[{"name":"starting_frame","doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","dtype":"int","shape":[null],"dims":["num_files"]}]},{"dtype":"text","name":"format","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","quantity":"?","default_value":"raw"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][y][x] or [frame][z][y][x].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"links":[{"name":"masked_imageseries","doc":"Link to ImageSeries object that this image mask is applied to.","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"distance","doc":"Distance from camera/monitor to target/eye.","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"},{"dtype":"text","name":"orientation","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int","name":"data","doc":"Index of the frame in the referenced ImageSeries.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]}],"links":[{"name":"indexed_timeseries","doc":"Link to ImageSeries object containing images that are indexed.","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]}]}:{"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"name":"acquisition","doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis."},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"}],"name":"analysis","doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs."},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"name":"notes","doc":"Any notes the user has about the dataset being stored","dtype":"text"}]}],"name":"scratch","doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"name":"processing","doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis."},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"presentation","doc":"Stimuli presented during the experiment."},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"templates","doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame."}],"name":"stimulus","doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file."},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"groups":[{"doc":"A data acquisition device, e.g. recording system.","quantity":"+","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device"}],"name":"devices","doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","quantity":"?"},{"datasets":[{"dtype":"text","name":"age","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","quantity":"?"},{"dtype":"isodatetime","name":"date_of_birth","doc":"Date of birth of subject. Can be supplied instead of 'age'.","quantity":"?"},{"dtype":"text","name":"description","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","quantity":"?"},{"dtype":"text","name":"genotype","doc":"Genetic strain. If absent, assume Wild Type (WT).","quantity":"?"},{"dtype":"text","name":"sex","doc":"Gender of subject.","quantity":"?"},{"dtype":"text","name":"species","doc":"Species of subject.","quantity":"?"},{"dtype":"text","name":"subject_id","doc":"ID of animal/person used/participating in experiment (lab convention).","quantity":"?"},{"dtype":"text","name":"weight","doc":"Weight at time of experiment, at time of surgery and at other important times.","quantity":"?"}],"name":"subject","doc":"Information about the animal or person from which the data was measured.","quantity":"?","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float","name":"x","doc":"x coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"y","doc":"y coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"z","doc":"z coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"imp","doc":"Impedance of the channel.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"location","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"filtering","doc":"Description of hardware filtering.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"group","doc":"Reference to the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"group_name","doc":"Name of the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"}],"name":"electrodes","doc":"A table of all electrodes (i.e. channels) used for recording.","quantity":"?","neurodata_type_inc":"DynamicTable"}],"name":"extracellular_ephys","doc":"Metadata related to extracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"name":"sweep_table","doc":"The table which groups different PatchClampSeries together.","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","name":"filtering","doc":"Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","quantity":"?"}],"name":"intracellular_ephys","doc":"Metadata related to intracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"name":"optogenetics","doc":"Metadata describing optogenetic stimuluation.","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"name":"optophysiology","doc":"Metadata related to optophysiology.","quantity":"?"}],"datasets":[{"dtype":"text","name":"data_collection","doc":"Notes about data collection and analysis.","quantity":"?"},{"dtype":"text","name":"experiment_description","doc":"General description of the experiment.","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","name":"experimenter","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","quantity":"?"},{"dtype":"text","name":"institution","doc":"Institution(s) where experiment was performed.","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","name":"keywords","doc":"Terms to search over.","quantity":"?"},{"dtype":"text","name":"lab","doc":"Laboratory where experiment was performed.","quantity":"?"},{"dtype":"text","name":"notes","doc":"Notes about the experiment.","quantity":"?"},{"dtype":"text","name":"pharmacology","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","quantity":"?"},{"dtype":"text","name":"protocol","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","name":"related_publications","doc":"Publication information. PMID, DOI, URL, etc.","quantity":"?"},{"dtype":"text","name":"session_id","doc":"Lab-specific ID for the session.","quantity":"?"},{"dtype":"text","name":"slices","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","quantity":"?"},{"dtype":"text","name":"source_script","doc":"Script file or link to public source code used to create this NWB file.","quantity":"?","attributes":[{"name":"file_name","doc":"Name of script file.","dtype":"text"}]},{"dtype":"text","name":"stimulus","doc":"Notes about stimuli, such as how and where they were presented.","quantity":"?"},{"dtype":"text","name":"surgery","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","quantity":"?"},{"dtype":"text","name":"virus","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","quantity":"?"}],"name":"general","doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them."},{"groups":[{"name":"epochs","doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"trials","doc":"Repeated experimental events that have a logical grouping.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"invalid_times","doc":"Time intervals that should be removed from analysis.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"name":"intervals","doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","quantity":"?"},{"name":"units","doc":"Data about sorted spike units.","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","name":"file_create_date","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array."},{"dtype":"text","name":"identifier","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files."},{"dtype":"text","name":"session_description","doc":"A description of the experimental session and data in the file."},{"dtype":"isodatetime","name":"session_start_time","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds."},{"dtype":"isodatetime","name":"timestamps_reference_time","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero)."}],"name":"root","doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"name":"nwb_version","doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","dtype":"text","value":"2.1.0"}]}]},1{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"Values of each feature at each time.","attributes":[{"name":"unit","doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"feature_units","doc":"Units of each feature.","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"features","doc":"Description of the features represented in TimeSeries::data."}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","name":"data","doc":"Annotations made during an experiment.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","name":"data","doc":"Use values >0 if interval started, <0 if interval ended.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"datasets":[{"dtype":"text","name":"band_name","doc":"Name of the band, e.g. theta.","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float","name":"band_limits","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_mean","doc":"The mean Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_stdev","doc":"The standard deviation of Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"}],"name":"bands","doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","name":"data","doc":"Data decomposed into frequency bands.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"no unit"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"metric","doc":"The metric used, e.g. phase, amplitude, power."}],"links":[{"name":"source_timeseries","doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"spike_times_index","doc":"Index into the spike_times dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"double","name":"spike_times","doc":"Spike times for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"obs_intervals_index","doc":"Index into the obs_intervals dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"double","name":"obs_intervals","doc":"Observation intervals for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"electrodes_index","doc":"Index into electrodes.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"name":"electrodes","doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"electrode_group","doc":"Electrode group that each spike unit came from.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_mean","doc":"Spike waveform mean for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_sd","doc":"Spike waveform standard deviation for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"meters"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"reference_frame","doc":"Description defining what exactly 'straight-ahead' means.","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]}~ {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Applied power for optogenetic stimulus, in watts.","attributes":[{"name":"unit","doc":"Unit of measurement for data, which is fixed to 'watts'.","dtype":"text","value":"watts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"links":[{"name":"site","doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of stimulation site."},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"text","name":"location","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."}],"links":[{"name":"device","doc":"Device that generated the stimulus.","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]}0`3#]p3#]3#]SNOD8XqxP>(HpHhr`?AB3#]3#]3#]GCOLp0{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Recorded voltage data.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Spike waveforms.","attributes":[{"name":"unit","doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","name":"description","doc":"Description of features (eg, ''PC1'') for each of the extracted features."},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","name":"features","doc":"Multi-dimensional array of features extracted from each event."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of events that features correspond to (can be a link)."},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","name":"detection_method","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values."},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"source_idx","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Timestamps of events, in seconds.","attributes":[{"name":"unit","doc":"Unit of measurement for event times, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"links":[{"name":"source_electricalseries","doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries description or comments field.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"links":[{"name":"device","doc":"Link to the device that was used to record from this electrode group.","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"name":"description","doc":"Description of this electrode group.","dtype":"text"},{"name":"location","doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","dtype":"text"}]},{"datasets":[{"dtype":"text","name":"waveform_filtering","doc":"Filtering applied to data before generating mean/sd"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_mean","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_sd","doc":"Stdev of waveforms for each cluster, using the same indices as in mean"}],"links":[{"name":"clustering_interface","doc":"Link to Clustering interface that was the source of the clustered data","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","name":"description","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)"},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"num","doc":"Cluster number of each event"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","name":"peak_over_rms","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric)."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module."}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}B{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Recorded voltage or current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float","name":"gain","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","quantity":"?"}],"links":[{"name":"electrode","doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded voltage.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps.","quantity":"?"},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms.","quantity":"?"},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads.","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps, fixed to 0.0."},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms, fixed to 0.0."},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads, fixed to 0.0."}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus current applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"capacitance_fast","doc":"Fast capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"capacitance_slow","doc":"Slow capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"resistance_comp_bandwidth","doc":"Resistance compensation bandwidth, in hertz.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","dtype":"text","value":"hertz"}]},{"dtype":"float32","name":"resistance_comp_correction","doc":"Resistance compensation correction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"resistance_comp_prediction","doc":"Resistance compensation prediction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"whole_cell_capacitance_comp","doc":"Whole cell capacitance compensation, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"whole_cell_series_resistance_comp","doc":"Whole cell series resistance compensation, in ohms.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus voltage applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of electrode (e.g., whole-cell, sharp, etc.)."},{"dtype":"text","name":"filtering","doc":"Electrode specific filtering.","quantity":"?"},{"dtype":"text","name":"initial_access_resistance","doc":"Initial access resistance.","quantity":"?"},{"dtype":"text","name":"location","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","quantity":"?"},{"dtype":"text","name":"resistance","doc":"Electrode resistance, in ohms.","quantity":"?"},{"dtype":"text","name":"seal","doc":"Information about seal used for recording.","quantity":"?"},{"dtype":"text","name":"slice","doc":"Information about slice used for recording.","quantity":"?"}],"links":[{"name":"device","doc":"Device that was used to record from this electrode.","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint64","name":"sweep_number","doc":"Sweep number of the PatchClampSeries in that row.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"name":"series","doc":"The PatchClampSeries with the sweep number in that row.","neurodata_type_inc":"VectorData"},{"name":"series_index","doc":"Index for series.","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]},{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":["width|height","width|height|depth"],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"name":"pmt_gain","doc":"Photomultiplier gain.","required":false,"dtype":"float32"},{"name":"scan_line_rate","doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","required":false,"dtype":"float32"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","name":"data","doc":"Signals from ROIs.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"name":"rois","doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. Each row in data should correspond to the signal from one ROI. Each element on the second dimension of data should correspond to the signal from one ROI.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"name":"reference_images","doc":"Image stacks that the segmentation masks apply to."}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"name":"image_mask","doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"pixel_mask_index","doc":"Index into pixel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float"}],"name":"pixel_mask","doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"voxel_mask_index","doc":"Index into voxel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float"}],"name":"voxel_mask","doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","neurodata_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorIndex"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this data was generated.","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"datasets":[{"dtype":"text","name":"description","doc":"Description or other notes about the channel."},{"dtype":"float","name":"emission_lambda","doc":"Emission wavelength for channel, in nm."}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"}],"datasets":[{"dtype":"text","name":"description","doc":"Description of the imaging plane.","quantity":"?"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"float","name":"imaging_rate","doc":"Rate that images are acquired, in Hz."},{"dtype":"text","name":"indicator","doc":"Calcium indicator."},{"dtype":"text","name":"location","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x|y|z"],["height","width","depth","x|y|z"]],"dtype":"float32","name":"manifold","doc":"Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","required":false,"dtype":"float","default_value":1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'.","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","name":"reference_frame","doc":"Describes position and reference frame of manifold based on position of first element in manifold. For example, text description of anatomical location or vectors needed to rotate to common anatomical axis (eg, AP/DV/ML). This field is necessary to interpret manifold. If manifold is not present then this field is not required.","quantity":"?"}],"links":[{"name":"device","doc":"Link to the Device object that was used to record from this electrode.","target_type":"Device"}],"doc":"An imaging plane and its metadata.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"groups":[{"groups":[{"name":"corrected","doc":"Image stack with frames shifted to the common coordinates.","neurodata_type_inc":"ImageSeries"},{"name":"xy_translation","doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","neurodata_type_inc":"TimeSeries"}],"links":[{"name":"original","doc":"Link to ImageSeries object that is being registered.","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"}]}{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_phase_map","doc":"Phase response to stimulus on the first measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row|column"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_power_map","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_phase_map","doc":"Phase response to stimulus on the second measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_power_map","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[2],"dims":["names"],"dtype":"text","name":"axis_descriptions","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta']."},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"focal_depth_image","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"focal_depth","doc":"Focal depth offset, in meters.","dtype":"float"},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"sign_map","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"vasculature_image","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}U{"namespaces":[{"doc":"NWB namespace","schema":[{"source":"nwb.base"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.1.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}P/././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.1.0_str_experimenter.nwb0000644000175100001730000042740014467767506022544 0ustar00runnerdockerHDF  /` TREEH1HEAP`H0 0 .speclocpHhTREEHEAPXPSNOD Hh(Pp P,H0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREEHEAPXexperimenter@ H nwb_version<=0?#]xSNODGCOLone experimenter 2019-11-27T17:32:33.693364-08:00ADDMEADDME 2019-11-27T17:32:33.692366-08:00 2019-11-27T17:32:33.692366-08:002.1.0core NWBFile $09c170b8-34a8-4768-8868-213051b95f41 G{"groups":[{"datasets":[{"dtype":"float","name":"start_time","doc":"Start time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"stop_time","doc":"Stop time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"text","name":"tags","doc":"User-defined tags that identify or categorize events.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"tags_index","doc":"Index for tags.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to.","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"name":"timeseries","doc":"An index into a TimeSeries object.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"timeseries_index","doc":"Index for timeseries.","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}84#]x4#](4#]84#]acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh-(  0 x(.8/p=0?8  2H4#]   S'HG y(@x:@x,1@x@x0GBG~ @x,GGUG H namespace Hneurodata_type H object_id$ PTREEhBHEAPXP?coreH?ATREEpFHEAPXB2.1.0HSNOD??ACETREE@pBHEAP`vSNODCCEX4#]GCOLx'S'{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_def":"NWBData"},{"doc":"Pointers that index data values.","neurodata_type_inc":"NWBData","neurodata_type_def":"Index","attributes":[{"name":"target","doc":"Target dataset that this index applies to.","dtype":{"target_type":"NWBData","reftype":"object"}}]},{"doc":"A 1-dimensional dataset. This can be indexed using a VectorIndex to encode a 2-dimensional ragged array in 1 dimension. The first vector is at VectorData[0:VectorIndex(0)+1]. The second vector is at VectorData[VectorIndex(0)+1:VectorIndex(1)+1]. And so on.","neurodata_type_inc":"NWBData","neurodata_type_def":"VectorData","attributes":[{"name":"description","doc":"Description of what these vectors represent.","dtype":"text"}]},{"doc":"An array of indices into the first dimension of the target VectorData. Can be used with VectorData to encode a 2-dimensional ragged array in 1 dimension.","neurodata_type_inc":"Index","neurodata_type_def":"VectorIndex","attributes":[{"name":"target","doc":"Reference to the target dataset that this index applies to.","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","neurodata_type_inc":"NWBData","neurodata_type_def":"ElementIdentifiers"},{"dtype":"int","doc":"A region/index into a DynamicTable.","neurodata_type_inc":"VectorData","neurodata_type_def":"DynamicTableRegion","attributes":[{"name":"table","doc":"Reference to the DynamicTable object that this region applies to.","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"name":"description","doc":"Description of what this table region points to.","dtype":"text"}]},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["num_x","num_y"],["num_x","num_y","(r, g, b)"],["num_x","num_y","(r, g, b, a)"]],"doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"name":"sync","doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"name":"data","doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"dtype":"float64","name":"starting_time","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","quantity":"?","attributes":[{"name":"rate","doc":"Sampling rate, in Hz.","dtype":"float32"},{"name":"unit","doc":"Unit of measurement for time, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","quantity":"?","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","name":"control","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","name":"control_description","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"name":"description","doc":"Description of this collection of processed data.","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A collection of images.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"name":"description","doc":"Description of this collection of images.","dtype":"text"}]},{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","neurodata_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorIndex"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). Apart from a column that contains unique identifiers for each row there are no other required datasets. Users are free to add any number of VectorData objects here. Table functionality is already supported through compound types, which is analogous to storing an array-of-structs. DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable. For example, DynamicTable was originally developed for storing trial data and spike unit metadata. Both of these use cases are expected to produce relatively small tables, so the spatial locality of multiple datasets present in a DynamicTable is not expected to have a significant performance impact. Additionally, requirements of trial and unit metadata tables are sufficiently diverse that performance implications can be overlooked in favor of usability.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DynamicTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}SNOD(FGXuh?qh4#]x4#]4#]4#]4#]nwb.basenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOLPy({"datasets":[{"shape":[null,null],"dims":["y","x"],"doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,3],"dims":["y","x","R, G, B"],"doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,4],"dims":["y","x","R, G, B, A"],"doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","y","x"],["frame","z","y","x"]],"dtype":"numeric","name":"data","doc":"Binary data representing images across frames.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","name":"dimension","doc":"Number of pixels on x, y, (and z) axes.","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","name":"external_file","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","quantity":"?","attributes":[{"name":"starting_frame","doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","dtype":"int","shape":[null],"dims":["num_files"]}]},{"dtype":"text","name":"format","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","quantity":"?","default_value":"raw"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][y][x] or [frame][z][y][x].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"links":[{"name":"masked_imageseries","doc":"Link to ImageSeries object that this image mask is applied to.","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"distance","doc":"Distance from camera/monitor to target/eye.","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"},{"dtype":"text","name":"orientation","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int","name":"data","doc":"Index of the frame in the referenced ImageSeries.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]}],"links":[{"name":"indexed_timeseries","doc":"Link to ImageSeries object containing images that are indexed.","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]}]}:{"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"name":"acquisition","doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis."},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"}],"name":"analysis","doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs."},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"name":"notes","doc":"Any notes the user has about the dataset being stored","dtype":"text"}]}],"name":"scratch","doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"name":"processing","doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis."},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"presentation","doc":"Stimuli presented during the experiment."},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"templates","doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame."}],"name":"stimulus","doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file."},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"groups":[{"doc":"A data acquisition device, e.g. recording system.","quantity":"+","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device"}],"name":"devices","doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","quantity":"?"},{"datasets":[{"dtype":"text","name":"age","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","quantity":"?"},{"dtype":"isodatetime","name":"date_of_birth","doc":"Date of birth of subject. Can be supplied instead of 'age'.","quantity":"?"},{"dtype":"text","name":"description","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","quantity":"?"},{"dtype":"text","name":"genotype","doc":"Genetic strain. If absent, assume Wild Type (WT).","quantity":"?"},{"dtype":"text","name":"sex","doc":"Gender of subject.","quantity":"?"},{"dtype":"text","name":"species","doc":"Species of subject.","quantity":"?"},{"dtype":"text","name":"subject_id","doc":"ID of animal/person used/participating in experiment (lab convention).","quantity":"?"},{"dtype":"text","name":"weight","doc":"Weight at time of experiment, at time of surgery and at other important times.","quantity":"?"}],"name":"subject","doc":"Information about the animal or person from which the data was measured.","quantity":"?","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float","name":"x","doc":"x coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"y","doc":"y coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"z","doc":"z coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"imp","doc":"Impedance of the channel.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"location","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"filtering","doc":"Description of hardware filtering.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"group","doc":"Reference to the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"group_name","doc":"Name of the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"}],"name":"electrodes","doc":"A table of all electrodes (i.e. channels) used for recording.","quantity":"?","neurodata_type_inc":"DynamicTable"}],"name":"extracellular_ephys","doc":"Metadata related to extracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"name":"sweep_table","doc":"The table which groups different PatchClampSeries together.","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","name":"filtering","doc":"Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","quantity":"?"}],"name":"intracellular_ephys","doc":"Metadata related to intracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"name":"optogenetics","doc":"Metadata describing optogenetic stimuluation.","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"name":"optophysiology","doc":"Metadata related to optophysiology.","quantity":"?"}],"datasets":[{"dtype":"text","name":"data_collection","doc":"Notes about data collection and analysis.","quantity":"?"},{"dtype":"text","name":"experiment_description","doc":"General description of the experiment.","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","name":"experimenter","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","quantity":"?"},{"dtype":"text","name":"institution","doc":"Institution(s) where experiment was performed.","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","name":"keywords","doc":"Terms to search over.","quantity":"?"},{"dtype":"text","name":"lab","doc":"Laboratory where experiment was performed.","quantity":"?"},{"dtype":"text","name":"notes","doc":"Notes about the experiment.","quantity":"?"},{"dtype":"text","name":"pharmacology","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","quantity":"?"},{"dtype":"text","name":"protocol","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","name":"related_publications","doc":"Publication information. PMID, DOI, URL, etc.","quantity":"?"},{"dtype":"text","name":"session_id","doc":"Lab-specific ID for the session.","quantity":"?"},{"dtype":"text","name":"slices","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","quantity":"?"},{"dtype":"text","name":"source_script","doc":"Script file or link to public source code used to create this NWB file.","quantity":"?","attributes":[{"name":"file_name","doc":"Name of script file.","dtype":"text"}]},{"dtype":"text","name":"stimulus","doc":"Notes about stimuli, such as how and where they were presented.","quantity":"?"},{"dtype":"text","name":"surgery","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","quantity":"?"},{"dtype":"text","name":"virus","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","quantity":"?"}],"name":"general","doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them."},{"groups":[{"name":"epochs","doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"trials","doc":"Repeated experimental events that have a logical grouping.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"invalid_times","doc":"Time intervals that should be removed from analysis.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"name":"intervals","doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","quantity":"?"},{"name":"units","doc":"Data about sorted spike units.","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","name":"file_create_date","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array."},{"dtype":"text","name":"identifier","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files."},{"dtype":"text","name":"session_description","doc":"A description of the experimental session and data in the file."},{"dtype":"isodatetime","name":"session_start_time","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds."},{"dtype":"isodatetime","name":"timestamps_reference_time","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero)."}],"name":"root","doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"name":"nwb_version","doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","dtype":"text","value":"2.1.0"}]}]},1{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"Values of each feature at each time.","attributes":[{"name":"unit","doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"feature_units","doc":"Units of each feature.","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"features","doc":"Description of the features represented in TimeSeries::data."}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","name":"data","doc":"Annotations made during an experiment.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","name":"data","doc":"Use values >0 if interval started, <0 if interval ended.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"datasets":[{"dtype":"text","name":"band_name","doc":"Name of the band, e.g. theta.","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float","name":"band_limits","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_mean","doc":"The mean Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_stdev","doc":"The standard deviation of Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"}],"name":"bands","doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","name":"data","doc":"Data decomposed into frequency bands.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"no unit"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"metric","doc":"The metric used, e.g. phase, amplitude, power."}],"links":[{"name":"source_timeseries","doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"spike_times_index","doc":"Index into the spike_times dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"double","name":"spike_times","doc":"Spike times for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"obs_intervals_index","doc":"Index into the obs_intervals dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"double","name":"obs_intervals","doc":"Observation intervals for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"electrodes_index","doc":"Index into electrodes.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"name":"electrodes","doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"electrode_group","doc":"Electrode group that each spike unit came from.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_mean","doc":"Spike waveform mean for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_sd","doc":"Spike waveform standard deviation for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"meters"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"reference_frame","doc":"Description defining what exactly 'straight-ahead' means.","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]}~ {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Applied power for optogenetic stimulus, in watts.","attributes":[{"name":"unit","doc":"Unit of measurement for data, which is fixed to 'watts'.","dtype":"text","value":"watts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"links":[{"name":"site","doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of stimulation site."},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"text","name":"location","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."}],"links":[{"name":"device","doc":"Device that generated the stimulus.","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]}04#]4#]4#]SNOD8sx@(rHtADE4#]4#]5#]GCOLp0{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Recorded voltage data.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Spike waveforms.","attributes":[{"name":"unit","doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","name":"description","doc":"Description of features (eg, ''PC1'') for each of the extracted features."},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","name":"features","doc":"Multi-dimensional array of features extracted from each event."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of events that features correspond to (can be a link)."},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","name":"detection_method","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values."},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"source_idx","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Timestamps of events, in seconds.","attributes":[{"name":"unit","doc":"Unit of measurement for event times, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"links":[{"name":"source_electricalseries","doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries description or comments field.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"links":[{"name":"device","doc":"Link to the device that was used to record from this electrode group.","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"name":"description","doc":"Description of this electrode group.","dtype":"text"},{"name":"location","doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","dtype":"text"}]},{"datasets":[{"dtype":"text","name":"waveform_filtering","doc":"Filtering applied to data before generating mean/sd"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_mean","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_sd","doc":"Stdev of waveforms for each cluster, using the same indices as in mean"}],"links":[{"name":"clustering_interface","doc":"Link to Clustering interface that was the source of the clustered data","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","name":"description","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)"},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"num","doc":"Cluster number of each event"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","name":"peak_over_rms","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric)."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module."}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}B{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Recorded voltage or current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float","name":"gain","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","quantity":"?"}],"links":[{"name":"electrode","doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded voltage.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps.","quantity":"?"},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms.","quantity":"?"},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads.","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps, fixed to 0.0."},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms, fixed to 0.0."},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads, fixed to 0.0."}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus current applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"capacitance_fast","doc":"Fast capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"capacitance_slow","doc":"Slow capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"resistance_comp_bandwidth","doc":"Resistance compensation bandwidth, in hertz.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","dtype":"text","value":"hertz"}]},{"dtype":"float32","name":"resistance_comp_correction","doc":"Resistance compensation correction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"resistance_comp_prediction","doc":"Resistance compensation prediction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"whole_cell_capacitance_comp","doc":"Whole cell capacitance compensation, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"whole_cell_series_resistance_comp","doc":"Whole cell series resistance compensation, in ohms.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus voltage applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of electrode (e.g., whole-cell, sharp, etc.)."},{"dtype":"text","name":"filtering","doc":"Electrode specific filtering.","quantity":"?"},{"dtype":"text","name":"initial_access_resistance","doc":"Initial access resistance.","quantity":"?"},{"dtype":"text","name":"location","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","quantity":"?"},{"dtype":"text","name":"resistance","doc":"Electrode resistance, in ohms.","quantity":"?"},{"dtype":"text","name":"seal","doc":"Information about seal used for recording.","quantity":"?"},{"dtype":"text","name":"slice","doc":"Information about slice used for recording.","quantity":"?"}],"links":[{"name":"device","doc":"Device that was used to record from this electrode.","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint64","name":"sweep_number","doc":"Sweep number of the PatchClampSeries in that row.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"name":"series","doc":"The PatchClampSeries with the sweep number in that row.","neurodata_type_inc":"VectorData"},{"name":"series_index","doc":"Index for series.","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]},{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":["width|height","width|height|depth"],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"name":"pmt_gain","doc":"Photomultiplier gain.","required":false,"dtype":"float32"},{"name":"scan_line_rate","doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","required":false,"dtype":"float32"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","name":"data","doc":"Signals from ROIs.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"name":"rois","doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. Each row in data should correspond to the signal from one ROI. Each element on the second dimension of data should correspond to the signal from one ROI.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"name":"reference_images","doc":"Image stacks that the segmentation masks apply to."}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"name":"image_mask","doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"pixel_mask_index","doc":"Index into pixel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float"}],"name":"pixel_mask","doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"voxel_mask_index","doc":"Index into voxel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float"}],"name":"voxel_mask","doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","neurodata_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorIndex"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this data was generated.","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"datasets":[{"dtype":"text","name":"description","doc":"Description or other notes about the channel."},{"dtype":"float","name":"emission_lambda","doc":"Emission wavelength for channel, in nm."}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"}],"datasets":[{"dtype":"text","name":"description","doc":"Description of the imaging plane.","quantity":"?"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"float","name":"imaging_rate","doc":"Rate that images are acquired, in Hz."},{"dtype":"text","name":"indicator","doc":"Calcium indicator."},{"dtype":"text","name":"location","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x|y|z"],["height","width","depth","x|y|z"]],"dtype":"float32","name":"manifold","doc":"Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","required":false,"dtype":"float","default_value":1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'.","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","name":"reference_frame","doc":"Describes position and reference frame of manifold based on position of first element in manifold. For example, text description of anatomical location or vectors needed to rotate to common anatomical axis (eg, AP/DV/ML). This field is necessary to interpret manifold. If manifold is not present then this field is not required.","quantity":"?"}],"links":[{"name":"device","doc":"Link to the Device object that was used to record from this electrode.","target_type":"Device"}],"doc":"An imaging plane and its metadata.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"groups":[{"groups":[{"name":"corrected","doc":"Image stack with frames shifted to the common coordinates.","neurodata_type_inc":"ImageSeries"},{"name":"xy_translation","doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","neurodata_type_inc":"TimeSeries"}],"links":[{"name":"original","doc":"Link to ImageSeries object that is being registered.","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"}]}{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_phase_map","doc":"Phase response to stimulus on the first measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row|column"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_power_map","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_phase_map","doc":"Phase response to stimulus on the second measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_power_map","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[2],"dims":["names"],"dtype":"text","name":"axis_descriptions","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta']."},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"focal_depth_image","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"focal_depth","doc":"Focal depth offset, in meters.","dtype":"float"},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"sign_map","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"vasculature_image","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}U{"namespaces":[{"doc":"NWB namespace","schema":[{"source":"nwb.base"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.1.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}P/././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.1.0_str_pub.nwb0000644000175100001730000042740014467767506020623 0ustar00runnerdockerHDF  /` TREEH1HEAP`H0 0 .speclocpHhTREEHEAPXPSNOD Hh(Pp P,H0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREEHEAPX related_publications8 H nwb_version<=0?#]xSNODGCOLone publication 2019-11-27T17:32:34.921967-08:00ADDMEADDME 2019-11-27T17:32:34.920969-08:00 2019-11-27T17:32:34.920969-08:002.1.0core NWBFile $d5544a2d-b296-4855-b7c2-9018c980a428 G{"groups":[{"datasets":[{"dtype":"float","name":"start_time","doc":"Start time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"stop_time","doc":"Stop time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"text","name":"tags","doc":"User-defined tags that identify or categorize events.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"tags_index","doc":"Index for tags.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to.","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"name":"timeseries","doc":"An index into a TimeSeries object.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"timeseries_index","doc":"Index for timeseries.","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}84#]x4#](4#]84#]acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh-(  0 x(.8/p=0?8  2H4#]   S'HG y(@x:@x,1@x@x0GBG~ @x,GGUG H namespace Hneurodata_type H object_id$ PTREEhBHEAPXP?coreH?ATREEpFHEAPXB2.1.0HSNOD??ACETREE@pBHEAP`vSNODCCEX4#]GCOLx'S'{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_def":"NWBData"},{"doc":"Pointers that index data values.","neurodata_type_inc":"NWBData","neurodata_type_def":"Index","attributes":[{"name":"target","doc":"Target dataset that this index applies to.","dtype":{"target_type":"NWBData","reftype":"object"}}]},{"doc":"A 1-dimensional dataset. This can be indexed using a VectorIndex to encode a 2-dimensional ragged array in 1 dimension. The first vector is at VectorData[0:VectorIndex(0)+1]. The second vector is at VectorData[VectorIndex(0)+1:VectorIndex(1)+1]. And so on.","neurodata_type_inc":"NWBData","neurodata_type_def":"VectorData","attributes":[{"name":"description","doc":"Description of what these vectors represent.","dtype":"text"}]},{"doc":"An array of indices into the first dimension of the target VectorData. Can be used with VectorData to encode a 2-dimensional ragged array in 1 dimension.","neurodata_type_inc":"Index","neurodata_type_def":"VectorIndex","attributes":[{"name":"target","doc":"Reference to the target dataset that this index applies to.","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","neurodata_type_inc":"NWBData","neurodata_type_def":"ElementIdentifiers"},{"dtype":"int","doc":"A region/index into a DynamicTable.","neurodata_type_inc":"VectorData","neurodata_type_def":"DynamicTableRegion","attributes":[{"name":"table","doc":"Reference to the DynamicTable object that this region applies to.","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"name":"description","doc":"Description of what this table region points to.","dtype":"text"}]},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["num_x","num_y"],["num_x","num_y","(r, g, b)"],["num_x","num_y","(r, g, b, a)"]],"doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"name":"sync","doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"name":"data","doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"dtype":"float64","name":"starting_time","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","quantity":"?","attributes":[{"name":"rate","doc":"Sampling rate, in Hz.","dtype":"float32"},{"name":"unit","doc":"Unit of measurement for time, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","quantity":"?","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","name":"control","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","name":"control_description","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"name":"description","doc":"Description of this collection of processed data.","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A collection of images.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"name":"description","doc":"Description of this collection of images.","dtype":"text"}]},{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","neurodata_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorIndex"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). Apart from a column that contains unique identifiers for each row there are no other required datasets. Users are free to add any number of VectorData objects here. Table functionality is already supported through compound types, which is analogous to storing an array-of-structs. DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable. For example, DynamicTable was originally developed for storing trial data and spike unit metadata. Both of these use cases are expected to produce relatively small tables, so the spatial locality of multiple datasets present in a DynamicTable is not expected to have a significant performance impact. Additionally, requirements of trial and unit metadata tables are sufficiently diverse that performance implications can be overlooked in favor of usability.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DynamicTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}SNOD(FGXuh?qh4#]x4#]4#]4#]4#]nwb.basenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOLPy({"datasets":[{"shape":[null,null],"dims":["y","x"],"doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,3],"dims":["y","x","R, G, B"],"doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,4],"dims":["y","x","R, G, B, A"],"doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","y","x"],["frame","z","y","x"]],"dtype":"numeric","name":"data","doc":"Binary data representing images across frames.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","name":"dimension","doc":"Number of pixels on x, y, (and z) axes.","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","name":"external_file","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","quantity":"?","attributes":[{"name":"starting_frame","doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","dtype":"int","shape":[null],"dims":["num_files"]}]},{"dtype":"text","name":"format","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","quantity":"?","default_value":"raw"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][y][x] or [frame][z][y][x].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"links":[{"name":"masked_imageseries","doc":"Link to ImageSeries object that this image mask is applied to.","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"distance","doc":"Distance from camera/monitor to target/eye.","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"},{"dtype":"text","name":"orientation","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int","name":"data","doc":"Index of the frame in the referenced ImageSeries.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]}],"links":[{"name":"indexed_timeseries","doc":"Link to ImageSeries object containing images that are indexed.","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]}]}:{"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"}],"name":"acquisition","doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis."},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"}],"name":"analysis","doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs."},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"name":"notes","doc":"Any notes the user has about the dataset being stored","dtype":"text"}]}],"name":"scratch","doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"name":"processing","doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis."},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"presentation","doc":"Stimuli presented during the experiment."},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"templates","doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame."}],"name":"stimulus","doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file."},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"groups":[{"doc":"A data acquisition device, e.g. recording system.","quantity":"+","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device"}],"name":"devices","doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","quantity":"?"},{"datasets":[{"dtype":"text","name":"age","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","quantity":"?"},{"dtype":"isodatetime","name":"date_of_birth","doc":"Date of birth of subject. Can be supplied instead of 'age'.","quantity":"?"},{"dtype":"text","name":"description","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","quantity":"?"},{"dtype":"text","name":"genotype","doc":"Genetic strain. If absent, assume Wild Type (WT).","quantity":"?"},{"dtype":"text","name":"sex","doc":"Gender of subject.","quantity":"?"},{"dtype":"text","name":"species","doc":"Species of subject.","quantity":"?"},{"dtype":"text","name":"subject_id","doc":"ID of animal/person used/participating in experiment (lab convention).","quantity":"?"},{"dtype":"text","name":"weight","doc":"Weight at time of experiment, at time of surgery and at other important times.","quantity":"?"}],"name":"subject","doc":"Information about the animal or person from which the data was measured.","quantity":"?","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float","name":"x","doc":"x coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"y","doc":"y coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"z","doc":"z coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"imp","doc":"Impedance of the channel.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"location","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"filtering","doc":"Description of hardware filtering.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"group","doc":"Reference to the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"group_name","doc":"Name of the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"}],"name":"electrodes","doc":"A table of all electrodes (i.e. channels) used for recording.","quantity":"?","neurodata_type_inc":"DynamicTable"}],"name":"extracellular_ephys","doc":"Metadata related to extracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"name":"sweep_table","doc":"The table which groups different PatchClampSeries together.","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","name":"filtering","doc":"Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","quantity":"?"}],"name":"intracellular_ephys","doc":"Metadata related to intracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"name":"optogenetics","doc":"Metadata describing optogenetic stimuluation.","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"name":"optophysiology","doc":"Metadata related to optophysiology.","quantity":"?"}],"datasets":[{"dtype":"text","name":"data_collection","doc":"Notes about data collection and analysis.","quantity":"?"},{"dtype":"text","name":"experiment_description","doc":"General description of the experiment.","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","name":"experimenter","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","quantity":"?"},{"dtype":"text","name":"institution","doc":"Institution(s) where experiment was performed.","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","name":"keywords","doc":"Terms to search over.","quantity":"?"},{"dtype":"text","name":"lab","doc":"Laboratory where experiment was performed.","quantity":"?"},{"dtype":"text","name":"notes","doc":"Notes about the experiment.","quantity":"?"},{"dtype":"text","name":"pharmacology","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","quantity":"?"},{"dtype":"text","name":"protocol","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","name":"related_publications","doc":"Publication information. PMID, DOI, URL, etc.","quantity":"?"},{"dtype":"text","name":"session_id","doc":"Lab-specific ID for the session.","quantity":"?"},{"dtype":"text","name":"slices","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","quantity":"?"},{"dtype":"text","name":"source_script","doc":"Script file or link to public source code used to create this NWB file.","quantity":"?","attributes":[{"name":"file_name","doc":"Name of script file.","dtype":"text"}]},{"dtype":"text","name":"stimulus","doc":"Notes about stimuli, such as how and where they were presented.","quantity":"?"},{"dtype":"text","name":"surgery","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","quantity":"?"},{"dtype":"text","name":"virus","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","quantity":"?"}],"name":"general","doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them."},{"groups":[{"name":"epochs","doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"trials","doc":"Repeated experimental events that have a logical grouping.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"invalid_times","doc":"Time intervals that should be removed from analysis.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"name":"intervals","doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","quantity":"?"},{"name":"units","doc":"Data about sorted spike units.","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","name":"file_create_date","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array."},{"dtype":"text","name":"identifier","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files."},{"dtype":"text","name":"session_description","doc":"A description of the experimental session and data in the file."},{"dtype":"isodatetime","name":"session_start_time","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds."},{"dtype":"isodatetime","name":"timestamps_reference_time","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero)."}],"name":"root","doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"name":"nwb_version","doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","dtype":"text","value":"2.1.0"}]}]},1{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"Values of each feature at each time.","attributes":[{"name":"unit","doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"feature_units","doc":"Units of each feature.","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"features","doc":"Description of the features represented in TimeSeries::data."}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","name":"data","doc":"Annotations made during an experiment.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","name":"data","doc":"Use values >0 if interval started, <0 if interval ended.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"datasets":[{"dtype":"text","name":"band_name","doc":"Name of the band, e.g. theta.","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float","name":"band_limits","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_mean","doc":"The mean Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_stdev","doc":"The standard deviation of Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"}],"name":"bands","doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","name":"data","doc":"Data decomposed into frequency bands.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"no unit"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"metric","doc":"The metric used, e.g. phase, amplitude, power."}],"links":[{"name":"source_timeseries","doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"spike_times_index","doc":"Index into the spike_times dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"double","name":"spike_times","doc":"Spike times for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"obs_intervals_index","doc":"Index into the obs_intervals dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"double","name":"obs_intervals","doc":"Observation intervals for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"electrodes_index","doc":"Index into electrodes.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"name":"electrodes","doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"electrode_group","doc":"Electrode group that each spike unit came from.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_mean","doc":"Spike waveform mean for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_sd","doc":"Spike waveform standard deviation for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"meters"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"reference_frame","doc":"Description defining what exactly 'straight-ahead' means.","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]}~ {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Applied power for optogenetic stimulus, in watts.","attributes":[{"name":"unit","doc":"Unit of measurement for data, which is fixed to 'watts'.","dtype":"text","value":"watts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"links":[{"name":"site","doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of stimulation site."},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"text","name":"location","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."}],"links":[{"name":"device","doc":"Device that generated the stimulus.","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]}04#]4#]4#]SNOD8sx@(rHtADE4#]4#]5#]GCOLp0{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Recorded voltage data.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Spike waveforms.","attributes":[{"name":"unit","doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","name":"description","doc":"Description of features (eg, ''PC1'') for each of the extracted features."},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","name":"features","doc":"Multi-dimensional array of features extracted from each event."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of events that features correspond to (can be a link)."},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","name":"detection_method","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values."},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"source_idx","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Timestamps of events, in seconds.","attributes":[{"name":"unit","doc":"Unit of measurement for event times, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"links":[{"name":"source_electricalseries","doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries description or comments field.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"links":[{"name":"device","doc":"Link to the device that was used to record from this electrode group.","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"name":"description","doc":"Description of this electrode group.","dtype":"text"},{"name":"location","doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","dtype":"text"}]},{"datasets":[{"dtype":"text","name":"waveform_filtering","doc":"Filtering applied to data before generating mean/sd"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_mean","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_sd","doc":"Stdev of waveforms for each cluster, using the same indices as in mean"}],"links":[{"name":"clustering_interface","doc":"Link to Clustering interface that was the source of the clustered data","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","name":"description","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)"},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"num","doc":"Cluster number of each event"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","name":"peak_over_rms","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric)."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module."}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}B{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Recorded voltage or current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float","name":"gain","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","quantity":"?"}],"links":[{"name":"electrode","doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded voltage.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps.","quantity":"?"},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms.","quantity":"?"},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads.","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps, fixed to 0.0."},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms, fixed to 0.0."},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads, fixed to 0.0."}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus current applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"capacitance_fast","doc":"Fast capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"capacitance_slow","doc":"Slow capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"resistance_comp_bandwidth","doc":"Resistance compensation bandwidth, in hertz.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","dtype":"text","value":"hertz"}]},{"dtype":"float32","name":"resistance_comp_correction","doc":"Resistance compensation correction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"resistance_comp_prediction","doc":"Resistance compensation prediction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"whole_cell_capacitance_comp","doc":"Whole cell capacitance compensation, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"whole_cell_series_resistance_comp","doc":"Whole cell series resistance compensation, in ohms.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus voltage applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of electrode (e.g., whole-cell, sharp, etc.)."},{"dtype":"text","name":"filtering","doc":"Electrode specific filtering.","quantity":"?"},{"dtype":"text","name":"initial_access_resistance","doc":"Initial access resistance.","quantity":"?"},{"dtype":"text","name":"location","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","quantity":"?"},{"dtype":"text","name":"resistance","doc":"Electrode resistance, in ohms.","quantity":"?"},{"dtype":"text","name":"seal","doc":"Information about seal used for recording.","quantity":"?"},{"dtype":"text","name":"slice","doc":"Information about slice used for recording.","quantity":"?"}],"links":[{"name":"device","doc":"Device that was used to record from this electrode.","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint64","name":"sweep_number","doc":"Sweep number of the PatchClampSeries in that row.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"name":"series","doc":"The PatchClampSeries with the sweep number in that row.","neurodata_type_inc":"VectorData"},{"name":"series_index","doc":"Index for series.","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]},{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":["width|height","width|height|depth"],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"name":"pmt_gain","doc":"Photomultiplier gain.","required":false,"dtype":"float32"},{"name":"scan_line_rate","doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","required":false,"dtype":"float32"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","name":"data","doc":"Signals from ROIs.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"name":"rois","doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. Each row in data should correspond to the signal from one ROI. Each element on the second dimension of data should correspond to the signal from one ROI.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"name":"reference_images","doc":"Image stacks that the segmentation masks apply to."}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"name":"image_mask","doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"pixel_mask_index","doc":"Index into pixel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float"}],"name":"pixel_mask","doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"voxel_mask_index","doc":"Index into voxel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float"}],"name":"voxel_mask","doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","neurodata_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorIndex"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this data was generated.","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"datasets":[{"dtype":"text","name":"description","doc":"Description or other notes about the channel."},{"dtype":"float","name":"emission_lambda","doc":"Emission wavelength for channel, in nm."}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"}],"datasets":[{"dtype":"text","name":"description","doc":"Description of the imaging plane.","quantity":"?"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"float","name":"imaging_rate","doc":"Rate that images are acquired, in Hz."},{"dtype":"text","name":"indicator","doc":"Calcium indicator."},{"dtype":"text","name":"location","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x|y|z"],["height","width","depth","x|y|z"]],"dtype":"float32","name":"manifold","doc":"Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","required":false,"dtype":"float","default_value":1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'.","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","name":"reference_frame","doc":"Describes position and reference frame of manifold based on position of first element in manifold. For example, text description of anatomical location or vectors needed to rotate to common anatomical axis (eg, AP/DV/ML). This field is necessary to interpret manifold. If manifold is not present then this field is not required.","quantity":"?"}],"links":[{"name":"device","doc":"Link to the Device object that was used to record from this electrode.","target_type":"Device"}],"doc":"An imaging plane and its metadata.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"groups":[{"groups":[{"name":"corrected","doc":"Image stack with frames shifted to the common coordinates.","neurodata_type_inc":"ImageSeries"},{"name":"xy_translation","doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","neurodata_type_inc":"TimeSeries"}],"links":[{"name":"original","doc":"Link to ImageSeries object that is being registered.","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"}]}{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_phase_map","doc":"Phase response to stimulus on the first measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row|column"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_power_map","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_phase_map","doc":"Phase response to stimulus on the second measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_power_map","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[2],"dims":["names"],"dtype":"text","name":"axis_descriptions","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta']."},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"focal_depth_image","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"focal_depth","doc":"Focal depth offset, in meters.","dtype":"float"},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"sign_map","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"vasculature_image","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}U{"namespaces":[{"doc":"NWB namespace","schema":[{"source":"nwb.base"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.1.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}P/././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.1.2_nwbfile.nwb0000644000175100001730000044150014467767506020572 0ustar00runnerdockerHDF  @C` TREEHP/HEAP`- 0 .speclocpHhTREEHEAPXPSNOD Hh(Pp PH0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREEHEAPXP H nwb_version1:<C'^x GCOL 2020-01-21T17:58:27.445200-08:00ADDMEADDME 2020-01-21T17:58:27.444165-08:00 2020-01-21T17:58:27.444165-08:002.1.0coreNWBFile $a0e3c42c-ec68-4e58-8505-ab7baa4c0ca8 {"groups":[{"datasets":[{"shape":[null],"dtype":"int","name":"indices","doc":"column indices"},{"shape":[null],"dtype":"int","name":"indptr","doc":"index pointer"},{"shape":[null],"name":"data","doc":"values in the matrix"}],"doc":"a compressed sparse row matrix","data_type_def":"CSRMatrix","attributes":[{"name":"shape","doc":"the shape of this sparse matrix","dtype":"int","shape":[2]}]}]} H{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.0.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]} G{"groups":[{"datasets":[{"dtype":"float","name":"start_time","doc":"Start time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"stop_time","doc":"Stop time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"text","name":"tags","doc":"User-defined tags that identify or categorize events.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"tags_index","doc":"Index for tags.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to.","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"name":"timeseries","doc":"An index into a TimeSeries object.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"timeseries_index","doc":"Index for timeseries.","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}h2C'^2C'^2C'^acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh*(  0 x+,p:<8  02C'^ H namespace Hneurodata_type H object_id$ P  xF H hbG y("<,1w4PTBPT~ ,PTPTqPTTREE@HEAPX =hdmf-commoncore8=?TREE DHEAPX?1.0.0HSNODZZ\X==?ACTREE(WHEAPX(Ctablesparsenamespace0SNOD`AAC3C'^GCOL{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"},{"doc":"Pointers that index data values.","data_type_inc":"Data","data_type_def":"Index","attributes":[{"name":"target","doc":"Target dataset that this index applies to.","dtype":{"target_type":"Data","reftype":"object"}}]},{"doc":"A 1-dimensional dataset. This can be indexed using a VectorIndex to encode a 2-dimensional ragged array in 1 dimension. The first vector is at VectorData[0:VectorIndex(0)+1]. The second vector is at VectorData[VectorIndex(0)+1:VectorIndex(1)+1]. And so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"name":"description","doc":"Description of what these vectors represent.","dtype":"text"}]},{"doc":"An array of indices into the first dimension of the target VectorData. Can be used with VectorData to encode a 2-dimensional ragged array in 1 dimension.","data_type_inc":"Index","data_type_def":"VectorIndex","attributes":[{"name":"target","doc":"Reference to the target dataset that this index applies to.","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"dtype":"int","doc":"A region/index into a DynamicTable.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"name":"table","doc":"Reference to the DynamicTable object that this region applies to.","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"name":"description","doc":"Description of what this table region points to.","dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","data_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","data_type_inc":"VectorIndex"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). Apart from a column that contains unique identifiers for each row there are no other required datasets. Users are free to add any number of VectorData objects here. Table functionality is already supported through compound types, which is analogous to storing an array-of-structs. DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable. For example, DynamicTable was originally developed for storing trial data and spike unit metadata. Both of these use cases are expected to produce relatively small tables, so the spatial locality of multiple datasets present in a DynamicTable is not expected to have a significant performance impact. Additionally, requirements of trial and unit metadata tables are sufficiently diverse that performance implications can be overlooked in favor of usability.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}SNODYpXhE3C'^ 3C'^Z\TREE`HEAPX\2.1.0Hx]_TREEzOHEAP`8SNODP]x]_03D'^GCOL8{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["num_x","num_y"],["num_x","num_y","(r, g, b)"],["num_x","num_y","(r, g, b, a)"]],"doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"name":"sync","doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"name":"data","doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"dtype":"float64","name":"starting_time","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","quantity":"?","attributes":[{"name":"rate","doc":"Sampling rate, in Hz.","dtype":"float32"},{"name":"unit","doc":"Unit of measurement for time, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","quantity":"?","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","name":"control","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","name":"control_description","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"name":"description","doc":"Description of this collection of processed data.","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A collection of images.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"name":"description","doc":"Description of this collection of images.","dtype":"text"}]}]}SNODRXaX(hPL{@3D'^P3D'^`3D'^p3D'^3D'^nwb.basenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOLy({"datasets":[{"shape":[null,null],"dims":["y","x"],"doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,3],"dims":["y","x","R, G, B"],"doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,4],"dims":["y","x","R, G, B, A"],"doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","y","x"],["frame","z","y","x"]],"dtype":"numeric","name":"data","doc":"Binary data representing images across frames.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","name":"dimension","doc":"Number of pixels on x, y, (and z) axes.","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","name":"external_file","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","quantity":"?","attributes":[{"name":"starting_frame","doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","dtype":"int","shape":[null],"dims":["num_files"]}]},{"dtype":"text","name":"format","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","quantity":"?","default_value":"raw"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][y][x] or [frame][z][y][x].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"links":[{"name":"masked_imageseries","doc":"Link to ImageSeries object that this image mask is applied to.","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"distance","doc":"Distance from camera/monitor to target/eye.","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"},{"dtype":"text","name":"orientation","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int","name":"data","doc":"Index of the frame in the referenced ImageSeries.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]}],"links":[{"name":"indexed_timeseries","doc":"Link to ImageSeries object containing images that are indexed.","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]}]}"<{"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"name":"acquisition","doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis."},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"name":"analysis","doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs."},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"name":"notes","doc":"Any notes the user has about the dataset being stored","dtype":"text"}]}],"name":"scratch","doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"name":"processing","doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis."},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"presentation","doc":"Stimuli presented during the experiment."},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"templates","doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame."}],"name":"stimulus","doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file."},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"groups":[{"doc":"A data acquisition device, e.g. recording system.","quantity":"+","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device"}],"name":"devices","doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","quantity":"?"},{"datasets":[{"dtype":"text","name":"age","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","quantity":"?"},{"dtype":"isodatetime","name":"date_of_birth","doc":"Date of birth of subject. Can be supplied instead of 'age'.","quantity":"?"},{"dtype":"text","name":"description","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","quantity":"?"},{"dtype":"text","name":"genotype","doc":"Genetic strain. If absent, assume Wild Type (WT).","quantity":"?"},{"dtype":"text","name":"sex","doc":"Gender of subject.","quantity":"?"},{"dtype":"text","name":"species","doc":"Species of subject.","quantity":"?"},{"dtype":"text","name":"subject_id","doc":"ID of animal/person used/participating in experiment (lab convention).","quantity":"?"},{"dtype":"text","name":"weight","doc":"Weight at time of experiment, at time of surgery and at other important times.","quantity":"?"}],"name":"subject","doc":"Information about the animal or person from which the data was measured.","quantity":"?","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float","name":"x","doc":"x coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"y","doc":"y coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"z","doc":"z coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"imp","doc":"Impedance of the channel.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"location","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"filtering","doc":"Description of hardware filtering.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"group","doc":"Reference to the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"group_name","doc":"Name of the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"}],"name":"electrodes","doc":"A table of all electrodes (i.e. channels) used for recording.","quantity":"?","neurodata_type_inc":"DynamicTable"}],"name":"extracellular_ephys","doc":"Metadata related to extracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"name":"sweep_table","doc":"The table which groups different PatchClampSeries together.","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","name":"filtering","doc":"Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","quantity":"?"}],"name":"intracellular_ephys","doc":"Metadata related to intracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"name":"optogenetics","doc":"Metadata describing optogenetic stimuluation.","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"name":"optophysiology","doc":"Metadata related to optophysiology.","quantity":"?"}],"datasets":[{"dtype":"text","name":"data_collection","doc":"Notes about data collection and analysis.","quantity":"?"},{"dtype":"text","name":"experiment_description","doc":"General description of the experiment.","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","name":"experimenter","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","quantity":"?"},{"dtype":"text","name":"institution","doc":"Institution(s) where experiment was performed.","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","name":"keywords","doc":"Terms to search over.","quantity":"?"},{"dtype":"text","name":"lab","doc":"Laboratory where experiment was performed.","quantity":"?"},{"dtype":"text","name":"notes","doc":"Notes about the experiment.","quantity":"?"},{"dtype":"text","name":"pharmacology","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","quantity":"?"},{"dtype":"text","name":"protocol","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","name":"related_publications","doc":"Publication information. PMID, DOI, URL, etc.","quantity":"?"},{"dtype":"text","name":"session_id","doc":"Lab-specific ID for the session.","quantity":"?"},{"dtype":"text","name":"slices","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","quantity":"?"},{"dtype":"text","name":"source_script","doc":"Script file or link to public source code used to create this NWB file.","quantity":"?","attributes":[{"name":"file_name","doc":"Name of script file.","dtype":"text"}]},{"dtype":"text","name":"stimulus","doc":"Notes about stimuli, such as how and where they were presented.","quantity":"?"},{"dtype":"text","name":"surgery","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","quantity":"?"},{"dtype":"text","name":"virus","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","quantity":"?"}],"name":"general","doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them."},{"groups":[{"name":"epochs","doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"trials","doc":"Repeated experimental events that have a logical grouping.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"invalid_times","doc":"Time intervals that should be removed from analysis.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"name":"intervals","doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","quantity":"?"},{"name":"units","doc":"Data about sorted spike units.","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","name":"file_create_date","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array."},{"dtype":"text","name":"identifier","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files."},{"dtype":"text","name":"session_description","doc":"A description of the experimental session and data in the file."},{"dtype":"isodatetime","name":"session_start_time","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds."},{"dtype":"isodatetime","name":"timestamps_reference_time","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero)."}],"name":"root","doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"name":"nwb_version","doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","dtype":"text","value":"2.1.0"}]}]},1{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"Values of each feature at each time.","attributes":[{"name":"unit","doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"feature_units","doc":"Units of each feature.","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"features","doc":"Description of the features represented in TimeSeries::data."}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","name":"data","doc":"Annotations made during an experiment.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","name":"data","doc":"Use values >0 if interval started, <0 if interval ended.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"datasets":[{"dtype":"text","name":"band_name","doc":"Name of the band, e.g. theta.","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float","name":"band_limits","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_mean","doc":"The mean Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_stdev","doc":"The standard deviation of Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"}],"name":"bands","doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","name":"data","doc":"Data decomposed into frequency bands.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"no unit"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"metric","doc":"The metric used, e.g. phase, amplitude, power."}],"links":[{"name":"source_timeseries","doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"spike_times_index","doc":"Index into the spike_times dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"double","name":"spike_times","doc":"Spike times for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"obs_intervals_index","doc":"Index into the obs_intervals dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"double","name":"obs_intervals","doc":"Observation intervals for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"electrodes_index","doc":"Index into electrodes.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"name":"electrodes","doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"electrode_group","doc":"Electrode group that each spike unit came from.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_mean","doc":"Spike waveform mean for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_sd","doc":"Spike waveform standard deviation for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"meters"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"reference_frame","doc":"Description defining what exactly 'straight-ahead' means.","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]}~ {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Applied power for optogenetic stimulus, in watts.","attributes":[{"name":"unit","doc":"Unit of measurement for data, which is fixed to 'watts'.","dtype":"text","value":"watts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"links":[{"name":"site","doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of stimulation site."},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"text","name":"location","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."}],"links":[{"name":"device","doc":"Device that generated the stimulus.","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]}`3D'^3D'^3D'^SNOD8~x`M(|HpNPQ3D'^3D'^3D'^GCOLw4{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Recorded voltage data.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float","name":"channel_conversion","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","quantity":"?","attributes":[{"name":"axis","doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","dtype":"int","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Spike waveforms.","attributes":[{"name":"unit","doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","name":"description","doc":"Description of features (eg, ''PC1'') for each of the extracted features."},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","name":"features","doc":"Multi-dimensional array of features extracted from each event."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of events that features correspond to (can be a link)."},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","name":"detection_method","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values."},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"source_idx","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Timestamps of events, in seconds.","attributes":[{"name":"unit","doc":"Unit of measurement for event times, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"links":[{"name":"source_electricalseries","doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries description or comments field.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"links":[{"name":"device","doc":"Link to the device that was used to record from this electrode group.","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"name":"description","doc":"Description of this electrode group.","dtype":"text"},{"name":"location","doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","dtype":"text"}]},{"datasets":[{"dtype":"text","name":"waveform_filtering","doc":"Filtering applied to data before generating mean/sd"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_mean","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_sd","doc":"Stdev of waveforms for each cluster, using the same indices as in mean"}],"links":[{"name":"clustering_interface","doc":"Link to Clustering interface that was the source of the clustered data","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","name":"description","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)"},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"num","doc":"Cluster number of each event"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","name":"peak_over_rms","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric)."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module."}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}B{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Recorded voltage or current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float","name":"gain","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","quantity":"?"}],"links":[{"name":"electrode","doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded voltage.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps.","quantity":"?"},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms.","quantity":"?"},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads.","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps, fixed to 0.0."},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms, fixed to 0.0."},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads, fixed to 0.0."}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus current applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"capacitance_fast","doc":"Fast capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"capacitance_slow","doc":"Slow capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"resistance_comp_bandwidth","doc":"Resistance compensation bandwidth, in hertz.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","dtype":"text","value":"hertz"}]},{"dtype":"float32","name":"resistance_comp_correction","doc":"Resistance compensation correction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"resistance_comp_prediction","doc":"Resistance compensation prediction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"whole_cell_capacitance_comp","doc":"Whole cell capacitance compensation, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"whole_cell_series_resistance_comp","doc":"Whole cell series resistance compensation, in ohms.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus voltage applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of electrode (e.g., whole-cell, sharp, etc.)."},{"dtype":"text","name":"filtering","doc":"Electrode specific filtering.","quantity":"?"},{"dtype":"text","name":"initial_access_resistance","doc":"Initial access resistance.","quantity":"?"},{"dtype":"text","name":"location","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","quantity":"?"},{"dtype":"text","name":"resistance","doc":"Electrode resistance, in ohms.","quantity":"?"},{"dtype":"text","name":"seal","doc":"Information about seal used for recording.","quantity":"?"},{"dtype":"text","name":"slice","doc":"Information about slice used for recording.","quantity":"?"}],"links":[{"name":"device","doc":"Device that was used to record from this electrode.","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint64","name":"sweep_number","doc":"Sweep number of the PatchClampSeries in that row.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"name":"series","doc":"The PatchClampSeries with the sweep number in that row.","neurodata_type_inc":"VectorData"},{"name":"series_index","doc":"Index for series.","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]},{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":["width|height","width|height|depth"],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"name":"pmt_gain","doc":"Photomultiplier gain.","required":false,"dtype":"float32"},{"name":"scan_line_rate","doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","required":false,"dtype":"float32"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","name":"data","doc":"Signals from ROIs.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"name":"rois","doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. Each row in data should correspond to the signal from one ROI. Each element on the second dimension of data should correspond to the signal from one ROI.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"name":"reference_images","doc":"Image stacks that the segmentation masks apply to."}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"name":"image_mask","doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"pixel_mask_index","doc":"Index into pixel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float"}],"name":"pixel_mask","doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"voxel_mask_index","doc":"Index into voxel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float"}],"name":"voxel_mask","doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","neurodata_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorIndex"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this data was generated.","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"datasets":[{"dtype":"text","name":"description","doc":"Description or other notes about the channel."},{"dtype":"float","name":"emission_lambda","doc":"Emission wavelength for channel, in nm."}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"}],"datasets":[{"dtype":"text","name":"description","doc":"Description of the imaging plane.","quantity":"?"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"float","name":"imaging_rate","doc":"Rate that images are acquired, in Hz."},{"dtype":"text","name":"indicator","doc":"Calcium indicator."},{"dtype":"text","name":"location","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x|y|z"],["height","width","depth","x|y|z"]],"dtype":"float32","name":"manifold","doc":"Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","required":false,"dtype":"float","default_value":1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'.","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","name":"reference_frame","doc":"Describes position and reference frame of manifold based on position of first element in manifold. For example, text description of anatomical location or vectors needed to rotate to common anatomical axis (eg, AP/DV/ML). This field is necessary to interpret manifold. If manifold is not present then this field is not required.","quantity":"?"}],"links":[{"name":"device","doc":"Link to the Device object that was used to record from this electrode.","target_type":"Device"}],"doc":"An imaging plane and its metadata.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"groups":[{"groups":[{"name":"corrected","doc":"Image stack with frames shifted to the common coordinates.","neurodata_type_inc":"ImageSeries"},{"name":"xy_translation","doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","neurodata_type_inc":"TimeSeries"}],"links":[{"name":"original","doc":"Link to ImageSeries object that is being registered.","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"}]}{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_phase_map","doc":"Phase response to stimulus on the first measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row|column"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_power_map","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_phase_map","doc":"Phase response to stimulus on the second measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_power_map","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[2],"dims":["names"],"dtype":"text","name":"axis_descriptions","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta']."},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"focal_depth_image","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"focal_depth","doc":"Focal depth offset, in meters.","dtype":"float"},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"sign_map","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"vasculature_image","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}q{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.1.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}2././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.1.2_str_experimenter.nwb0000644000175100001730000044262014467767506022547 0ustar00runnerdockerHDF  E` TREEH1HEAP`H0 0 .speclocpHhTREEHEAPXPSNOD Hh(Pp P,H0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREEHEAPXexperimenter@ H nwb_version<=0?E'^xSNODGCOLone experimenter 2020-01-21T17:58:29.172657-08:00ADDMEADDME 2020-01-21T17:58:29.171660-08:00 2020-01-21T17:58:29.171660-08:002.1.0core NWBFile $62787364-9064-441d-a0ac-d7d735042f82 {"groups":[{"datasets":[{"shape":[null],"dtype":"int","name":"indices","doc":"column indices"},{"shape":[null],"dtype":"int","name":"indptr","doc":"index pointer"},{"shape":[null],"name":"data","doc":"values in the matrix"}],"doc":"a compressed sparse row matrix","data_type_def":"CSRMatrix","attributes":[{"name":"shape","doc":"the shape of this sparse matrix","dtype":"int","shape":[2]}]}]} H{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.0.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]} G{"groups":[{"datasets":[{"dtype":"float","name":"start_time","doc":"Start time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"stop_time","doc":"Stop time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"text","name":"tags","doc":"User-defined tags that identify or categorize events.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"tags_index","doc":"Index for tags.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to.","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"name":"timeseries","doc":"An index into a TimeSeries object.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"timeseries_index","doc":"Index for timeseries.","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}H4E'^x4E'^(4E'^84E'^acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh-(  0 x(.8/p=0?8  2H4E'^   H H dG y("<,1w4VBV~ ,VVqV H namespace Hneurodata_type H object_id$ PTREEhBHEAPX P?hdmf-commoncore8?ATREEpFHEAPXB1.0.0HSNOD\](_??ACETREExYHEAPX(Ftablesparsenamespace0SNODCCEX4E'^GCOL{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"},{"doc":"Pointers that index data values.","data_type_inc":"Data","data_type_def":"Index","attributes":[{"name":"target","doc":"Target dataset that this index applies to.","dtype":{"target_type":"Data","reftype":"object"}}]},{"doc":"A 1-dimensional dataset. This can be indexed using a VectorIndex to encode a 2-dimensional ragged array in 1 dimension. The first vector is at VectorData[0:VectorIndex(0)+1]. The second vector is at VectorData[VectorIndex(0)+1:VectorIndex(1)+1]. And so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"name":"description","doc":"Description of what these vectors represent.","dtype":"text"}]},{"doc":"An array of indices into the first dimension of the target VectorData. Can be used with VectorData to encode a 2-dimensional ragged array in 1 dimension.","data_type_inc":"Index","data_type_def":"VectorIndex","attributes":[{"name":"target","doc":"Reference to the target dataset that this index applies to.","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"dtype":"int","doc":"A region/index into a DynamicTable.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"name":"table","doc":"Reference to the DynamicTable object that this region applies to.","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"name":"description","doc":"Description of what this table region points to.","dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","data_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","data_type_inc":"VectorIndex"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). Apart from a column that contains unique identifiers for each row there are no other required datasets. Users are free to add any number of VectorData objects here. Table functionality is already supported through compound types, which is analogous to storing an array-of-structs. DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable. For example, DynamicTable was originally developed for storing trial data and spike unit metadata. Both of these use cases are expected to produce relatively small tables, so the spatial locality of multiple datasets present in a DynamicTable is not expected to have a significant performance impact. Additionally, requirements of trial and unit metadata tables are sufficiently diverse that performance implications can be overlooked in favor of usability.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}SNOD[ZGh4E'^x4E'^](_TREE`bHEAPXH_2.1.0H_aTREE|QHEAP`SNOD__a4F'^GCOL8{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["num_x","num_y"],["num_x","num_y","(r, g, b)"],["num_x","num_y","(r, g, b, a)"]],"doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"name":"sync","doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"name":"data","doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"dtype":"float64","name":"starting_time","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","quantity":"?","attributes":[{"name":"rate","doc":"Sampling rate, in Hz.","dtype":"float32"},{"name":"unit","doc":"Unit of measurement for time, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","quantity":"?","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","name":"control","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","name":"control_description","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"name":"description","doc":"Description of this collection of processed data.","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A collection of images.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"name":"description","doc":"Description of this collection of images.","dtype":"text"}]}]}SNOD8UcXxhN8~4F'^4F'^4F'^4F'^4F'^nwb.basenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOLy({"datasets":[{"shape":[null,null],"dims":["y","x"],"doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,3],"dims":["y","x","R, G, B"],"doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,4],"dims":["y","x","R, G, B, A"],"doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","y","x"],["frame","z","y","x"]],"dtype":"numeric","name":"data","doc":"Binary data representing images across frames.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","name":"dimension","doc":"Number of pixels on x, y, (and z) axes.","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","name":"external_file","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","quantity":"?","attributes":[{"name":"starting_frame","doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","dtype":"int","shape":[null],"dims":["num_files"]}]},{"dtype":"text","name":"format","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","quantity":"?","default_value":"raw"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][y][x] or [frame][z][y][x].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"links":[{"name":"masked_imageseries","doc":"Link to ImageSeries object that this image mask is applied to.","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"distance","doc":"Distance from camera/monitor to target/eye.","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"},{"dtype":"text","name":"orientation","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int","name":"data","doc":"Index of the frame in the referenced ImageSeries.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]}],"links":[{"name":"indexed_timeseries","doc":"Link to ImageSeries object containing images that are indexed.","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]}]}"<{"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"name":"acquisition","doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis."},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"name":"analysis","doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs."},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"name":"notes","doc":"Any notes the user has about the dataset being stored","dtype":"text"}]}],"name":"scratch","doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"name":"processing","doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis."},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"presentation","doc":"Stimuli presented during the experiment."},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"templates","doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame."}],"name":"stimulus","doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file."},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"groups":[{"doc":"A data acquisition device, e.g. recording system.","quantity":"+","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device"}],"name":"devices","doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","quantity":"?"},{"datasets":[{"dtype":"text","name":"age","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","quantity":"?"},{"dtype":"isodatetime","name":"date_of_birth","doc":"Date of birth of subject. Can be supplied instead of 'age'.","quantity":"?"},{"dtype":"text","name":"description","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","quantity":"?"},{"dtype":"text","name":"genotype","doc":"Genetic strain. If absent, assume Wild Type (WT).","quantity":"?"},{"dtype":"text","name":"sex","doc":"Gender of subject.","quantity":"?"},{"dtype":"text","name":"species","doc":"Species of subject.","quantity":"?"},{"dtype":"text","name":"subject_id","doc":"ID of animal/person used/participating in experiment (lab convention).","quantity":"?"},{"dtype":"text","name":"weight","doc":"Weight at time of experiment, at time of surgery and at other important times.","quantity":"?"}],"name":"subject","doc":"Information about the animal or person from which the data was measured.","quantity":"?","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float","name":"x","doc":"x coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"y","doc":"y coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"z","doc":"z coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"imp","doc":"Impedance of the channel.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"location","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"filtering","doc":"Description of hardware filtering.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"group","doc":"Reference to the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"group_name","doc":"Name of the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"}],"name":"electrodes","doc":"A table of all electrodes (i.e. channels) used for recording.","quantity":"?","neurodata_type_inc":"DynamicTable"}],"name":"extracellular_ephys","doc":"Metadata related to extracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"name":"sweep_table","doc":"The table which groups different PatchClampSeries together.","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","name":"filtering","doc":"Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","quantity":"?"}],"name":"intracellular_ephys","doc":"Metadata related to intracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"name":"optogenetics","doc":"Metadata describing optogenetic stimuluation.","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"name":"optophysiology","doc":"Metadata related to optophysiology.","quantity":"?"}],"datasets":[{"dtype":"text","name":"data_collection","doc":"Notes about data collection and analysis.","quantity":"?"},{"dtype":"text","name":"experiment_description","doc":"General description of the experiment.","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","name":"experimenter","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","quantity":"?"},{"dtype":"text","name":"institution","doc":"Institution(s) where experiment was performed.","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","name":"keywords","doc":"Terms to search over.","quantity":"?"},{"dtype":"text","name":"lab","doc":"Laboratory where experiment was performed.","quantity":"?"},{"dtype":"text","name":"notes","doc":"Notes about the experiment.","quantity":"?"},{"dtype":"text","name":"pharmacology","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","quantity":"?"},{"dtype":"text","name":"protocol","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","name":"related_publications","doc":"Publication information. PMID, DOI, URL, etc.","quantity":"?"},{"dtype":"text","name":"session_id","doc":"Lab-specific ID for the session.","quantity":"?"},{"dtype":"text","name":"slices","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","quantity":"?"},{"dtype":"text","name":"source_script","doc":"Script file or link to public source code used to create this NWB file.","quantity":"?","attributes":[{"name":"file_name","doc":"Name of script file.","dtype":"text"}]},{"dtype":"text","name":"stimulus","doc":"Notes about stimuli, such as how and where they were presented.","quantity":"?"},{"dtype":"text","name":"surgery","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","quantity":"?"},{"dtype":"text","name":"virus","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","quantity":"?"}],"name":"general","doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them."},{"groups":[{"name":"epochs","doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"trials","doc":"Repeated experimental events that have a logical grouping.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"invalid_times","doc":"Time intervals that should be removed from analysis.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"name":"intervals","doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","quantity":"?"},{"name":"units","doc":"Data about sorted spike units.","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","name":"file_create_date","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array."},{"dtype":"text","name":"identifier","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files."},{"dtype":"text","name":"session_description","doc":"A description of the experimental session and data in the file."},{"dtype":"isodatetime","name":"session_start_time","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds."},{"dtype":"isodatetime","name":"timestamps_reference_time","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero)."}],"name":"root","doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"name":"nwb_version","doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","dtype":"text","value":"2.1.0"}]}]},1{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"Values of each feature at each time.","attributes":[{"name":"unit","doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"feature_units","doc":"Units of each feature.","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"features","doc":"Description of the features represented in TimeSeries::data."}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","name":"data","doc":"Annotations made during an experiment.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","name":"data","doc":"Use values >0 if interval started, <0 if interval ended.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"datasets":[{"dtype":"text","name":"band_name","doc":"Name of the band, e.g. theta.","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float","name":"band_limits","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_mean","doc":"The mean Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_stdev","doc":"The standard deviation of Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"}],"name":"bands","doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","name":"data","doc":"Data decomposed into frequency bands.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"no unit"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"metric","doc":"The metric used, e.g. phase, amplitude, power."}],"links":[{"name":"source_timeseries","doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"spike_times_index","doc":"Index into the spike_times dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"double","name":"spike_times","doc":"Spike times for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"obs_intervals_index","doc":"Index into the obs_intervals dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"double","name":"obs_intervals","doc":"Observation intervals for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"electrodes_index","doc":"Index into electrodes.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"name":"electrodes","doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"electrode_group","doc":"Electrode group that each spike unit came from.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_mean","doc":"Spike waveform mean for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_sd","doc":"Spike waveform standard deviation for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"meters"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"reference_frame","doc":"Description defining what exactly 'straight-ahead' means.","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]}~ {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Applied power for optogenetic stimulus, in watts.","attributes":[{"name":"unit","doc":"Unit of measurement for data, which is fixed to 'watts'.","dtype":"text","value":"watts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"links":[{"name":"site","doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of stimulation site."},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"text","name":"location","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."}],"links":[{"name":"device","doc":"Device that generated the stimulus.","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]}`4F'^4F'^5F'^SNOD8XxO(HHhPS(T5F'^(5F'^85F'^GCOLw4{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Recorded voltage data.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float","name":"channel_conversion","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","quantity":"?","attributes":[{"name":"axis","doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","dtype":"int","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Spike waveforms.","attributes":[{"name":"unit","doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","name":"description","doc":"Description of features (eg, ''PC1'') for each of the extracted features."},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","name":"features","doc":"Multi-dimensional array of features extracted from each event."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of events that features correspond to (can be a link)."},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","name":"detection_method","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values."},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"source_idx","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Timestamps of events, in seconds.","attributes":[{"name":"unit","doc":"Unit of measurement for event times, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"links":[{"name":"source_electricalseries","doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries description or comments field.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"links":[{"name":"device","doc":"Link to the device that was used to record from this electrode group.","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"name":"description","doc":"Description of this electrode group.","dtype":"text"},{"name":"location","doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","dtype":"text"}]},{"datasets":[{"dtype":"text","name":"waveform_filtering","doc":"Filtering applied to data before generating mean/sd"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_mean","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_sd","doc":"Stdev of waveforms for each cluster, using the same indices as in mean"}],"links":[{"name":"clustering_interface","doc":"Link to Clustering interface that was the source of the clustered data","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","name":"description","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)"},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"num","doc":"Cluster number of each event"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","name":"peak_over_rms","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric)."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module."}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}B{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Recorded voltage or current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float","name":"gain","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","quantity":"?"}],"links":[{"name":"electrode","doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded voltage.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps.","quantity":"?"},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms.","quantity":"?"},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads.","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps, fixed to 0.0."},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms, fixed to 0.0."},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads, fixed to 0.0."}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus current applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"capacitance_fast","doc":"Fast capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"capacitance_slow","doc":"Slow capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"resistance_comp_bandwidth","doc":"Resistance compensation bandwidth, in hertz.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","dtype":"text","value":"hertz"}]},{"dtype":"float32","name":"resistance_comp_correction","doc":"Resistance compensation correction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"resistance_comp_prediction","doc":"Resistance compensation prediction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"whole_cell_capacitance_comp","doc":"Whole cell capacitance compensation, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"whole_cell_series_resistance_comp","doc":"Whole cell series resistance compensation, in ohms.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus voltage applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of electrode (e.g., whole-cell, sharp, etc.)."},{"dtype":"text","name":"filtering","doc":"Electrode specific filtering.","quantity":"?"},{"dtype":"text","name":"initial_access_resistance","doc":"Initial access resistance.","quantity":"?"},{"dtype":"text","name":"location","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","quantity":"?"},{"dtype":"text","name":"resistance","doc":"Electrode resistance, in ohms.","quantity":"?"},{"dtype":"text","name":"seal","doc":"Information about seal used for recording.","quantity":"?"},{"dtype":"text","name":"slice","doc":"Information about slice used for recording.","quantity":"?"}],"links":[{"name":"device","doc":"Device that was used to record from this electrode.","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint64","name":"sweep_number","doc":"Sweep number of the PatchClampSeries in that row.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"name":"series","doc":"The PatchClampSeries with the sweep number in that row.","neurodata_type_inc":"VectorData"},{"name":"series_index","doc":"Index for series.","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]},{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":["width|height","width|height|depth"],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"name":"pmt_gain","doc":"Photomultiplier gain.","required":false,"dtype":"float32"},{"name":"scan_line_rate","doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","required":false,"dtype":"float32"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","name":"data","doc":"Signals from ROIs.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"name":"rois","doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. Each row in data should correspond to the signal from one ROI. Each element on the second dimension of data should correspond to the signal from one ROI.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"name":"reference_images","doc":"Image stacks that the segmentation masks apply to."}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"name":"image_mask","doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"pixel_mask_index","doc":"Index into pixel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float"}],"name":"pixel_mask","doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"voxel_mask_index","doc":"Index into voxel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float"}],"name":"voxel_mask","doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","neurodata_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorIndex"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this data was generated.","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"datasets":[{"dtype":"text","name":"description","doc":"Description or other notes about the channel."},{"dtype":"float","name":"emission_lambda","doc":"Emission wavelength for channel, in nm."}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"}],"datasets":[{"dtype":"text","name":"description","doc":"Description of the imaging plane.","quantity":"?"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"float","name":"imaging_rate","doc":"Rate that images are acquired, in Hz."},{"dtype":"text","name":"indicator","doc":"Calcium indicator."},{"dtype":"text","name":"location","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x|y|z"],["height","width","depth","x|y|z"]],"dtype":"float32","name":"manifold","doc":"Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","required":false,"dtype":"float","default_value":1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'.","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","name":"reference_frame","doc":"Describes position and reference frame of manifold based on position of first element in manifold. For example, text description of anatomical location or vectors needed to rotate to common anatomical axis (eg, AP/DV/ML). This field is necessary to interpret manifold. If manifold is not present then this field is not required.","quantity":"?"}],"links":[{"name":"device","doc":"Link to the Device object that was used to record from this electrode.","target_type":"Device"}],"doc":"An imaging plane and its metadata.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"groups":[{"groups":[{"name":"corrected","doc":"Image stack with frames shifted to the common coordinates.","neurodata_type_inc":"ImageSeries"},{"name":"xy_translation","doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","neurodata_type_inc":"TimeSeries"}],"links":[{"name":"original","doc":"Link to ImageSeries object that is being registered.","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"}]}{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_phase_map","doc":"Phase response to stimulus on the first measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row|column"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_power_map","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_phase_map","doc":"Phase response to stimulus on the second measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_power_map","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[2],"dims":["names"],"dtype":"text","name":"axis_descriptions","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta']."},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"focal_depth_image","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"focal_depth","doc":"Focal depth offset, in meters.","dtype":"float"},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"sign_map","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"vasculature_image","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}q{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.1.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}2././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.1.2_str_pub.nwb0000644000175100001730000044262014467767506020626 0ustar00runnerdockerHDF  E` TREEH1HEAP`H0 0 .speclocpHhTREEHEAPXPSNOD Hh(Pp P,H0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREEHEAPX related_publications8 H nwb_version<=0?F'^xSNODGCOLone publication 2020-01-21T17:58:30.813577-08:00ADDMEADDME 2020-01-21T17:58:30.811582-08:00 2020-01-21T17:58:30.811582-08:002.1.0core NWBFile $643f1ae4-e31c-4349-a1ee-f3a09b7fd312 {"groups":[{"datasets":[{"shape":[null],"dtype":"int","name":"indices","doc":"column indices"},{"shape":[null],"dtype":"int","name":"indptr","doc":"index pointer"},{"shape":[null],"name":"data","doc":"values in the matrix"}],"doc":"a compressed sparse row matrix","data_type_def":"CSRMatrix","attributes":[{"name":"shape","doc":"the shape of this sparse matrix","dtype":"int","shape":[2]}]}]} H{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.0.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]} G{"groups":[{"datasets":[{"dtype":"float","name":"start_time","doc":"Start time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"stop_time","doc":"Stop time of epoch, in seconds.","neurodata_type_inc":"VectorData"},{"dtype":"text","name":"tags","doc":"User-defined tags that identify or categorize events.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"tags_index","doc":"Index for tags.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to.","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"name":"timeseries","doc":"An index into a TimeSeries object.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"timeseries_index","doc":"Index for timeseries.","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}H4F'^x4F'^(4F'^84F'^acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh-(  0 x(.8/p=0?8  2H4F'^   H H dG y("<,1w4VBV~ ,VVqV H namespace Hneurodata_type H object_id$ PTREEhBHEAPX P?hdmf-commoncore8?ATREEpFHEAPXB1.0.0HSNOD\](_??ACETREExYHEAPX(Ftablesparsenamespace0SNODCCEX4F'^GCOL{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"},{"doc":"Pointers that index data values.","data_type_inc":"Data","data_type_def":"Index","attributes":[{"name":"target","doc":"Target dataset that this index applies to.","dtype":{"target_type":"Data","reftype":"object"}}]},{"doc":"A 1-dimensional dataset. This can be indexed using a VectorIndex to encode a 2-dimensional ragged array in 1 dimension. The first vector is at VectorData[0:VectorIndex(0)+1]. The second vector is at VectorData[VectorIndex(0)+1:VectorIndex(1)+1]. And so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"name":"description","doc":"Description of what these vectors represent.","dtype":"text"}]},{"doc":"An array of indices into the first dimension of the target VectorData. Can be used with VectorData to encode a 2-dimensional ragged array in 1 dimension.","data_type_inc":"Index","data_type_def":"VectorIndex","attributes":[{"name":"target","doc":"Reference to the target dataset that this index applies to.","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"dtype":"int","doc":"A region/index into a DynamicTable.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"name":"table","doc":"Reference to the DynamicTable object that this region applies to.","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"name":"description","doc":"Description of what this table region points to.","dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","data_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","data_type_inc":"VectorIndex"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). Apart from a column that contains unique identifiers for each row there are no other required datasets. Users are free to add any number of VectorData objects here. Table functionality is already supported through compound types, which is analogous to storing an array-of-structs. DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable. For example, DynamicTable was originally developed for storing trial data and spike unit metadata. Both of these use cases are expected to produce relatively small tables, so the spatial locality of multiple datasets present in a DynamicTable is not expected to have a significant performance impact. Additionally, requirements of trial and unit metadata tables are sufficiently diverse that performance implications can be overlooked in favor of usability.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}SNOD[ZGh4F'^x4F'^](_TREE`bHEAPXH_2.1.0H_aTREE|QHEAP`SNOD__a4H'^GCOL8{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["num_x","num_y"],["num_x","num_y","(r, g, b)"],["num_x","num_y","(r, g, b, a)"]],"doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"name":"sync","doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"name":"data","doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"dtype":"float64","name":"starting_time","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","quantity":"?","attributes":[{"name":"rate","doc":"Sampling rate, in Hz.","dtype":"float32"},{"name":"unit","doc":"Unit of measurement for time, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","quantity":"?","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","name":"control","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","name":"control_description","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"name":"description","doc":"Description of this collection of processed data.","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A collection of images.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"name":"description","doc":"Description of this collection of images.","dtype":"text"}]}]}SNOD8UcXxhN8~4H'^4H'^4H'^4H'^4H'^nwb.basenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOLy({"datasets":[{"shape":[null,null],"dims":["y","x"],"doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,3],"dims":["y","x","R, G, B"],"doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]},{"shape":[null,null,4],"dims":["y","x","R, G, B, A"],"doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage","attributes":[{"name":"resolution","doc":"Pixel resolution of the image, in pixels per centimeter.","required":false,"dtype":"float"},{"name":"description","doc":"Description of the image.","required":false,"dtype":"text"}]}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","y","x"],["frame","z","y","x"]],"dtype":"numeric","name":"data","doc":"Binary data representing images across frames.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","name":"dimension","doc":"Number of pixels on x, y, (and z) axes.","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","name":"external_file","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","quantity":"?","attributes":[{"name":"starting_frame","doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","dtype":"int","shape":[null],"dims":["num_files"]}]},{"dtype":"text","name":"format","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","quantity":"?","default_value":"raw"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][y][x] or [frame][z][y][x].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"links":[{"name":"masked_imageseries","doc":"Link to ImageSeries object that this image mask is applied to.","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"distance","doc":"Distance from camera/monitor to target/eye.","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"},{"dtype":"text","name":"orientation","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int","name":"data","doc":"Index of the frame in the referenced ImageSeries.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]}],"links":[{"name":"indexed_timeseries","doc":"Link to ImageSeries object containing images that are indexed.","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]}]}"<{"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"name":"acquisition","doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis."},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"name":"analysis","doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs."},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"name":"notes","doc":"Any notes the user has about the dataset being stored","dtype":"text"}]}],"name":"scratch","doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"name":"processing","doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis."},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"presentation","doc":"Stimuli presented during the experiment."},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"name":"templates","doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame."}],"name":"stimulus","doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file."},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"groups":[{"doc":"A data acquisition device, e.g. recording system.","quantity":"+","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device"}],"name":"devices","doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","quantity":"?"},{"datasets":[{"dtype":"text","name":"age","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","quantity":"?"},{"dtype":"isodatetime","name":"date_of_birth","doc":"Date of birth of subject. Can be supplied instead of 'age'.","quantity":"?"},{"dtype":"text","name":"description","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","quantity":"?"},{"dtype":"text","name":"genotype","doc":"Genetic strain. If absent, assume Wild Type (WT).","quantity":"?"},{"dtype":"text","name":"sex","doc":"Gender of subject.","quantity":"?"},{"dtype":"text","name":"species","doc":"Species of subject.","quantity":"?"},{"dtype":"text","name":"subject_id","doc":"ID of animal/person used/participating in experiment (lab convention).","quantity":"?"},{"dtype":"text","name":"weight","doc":"Weight at time of experiment, at time of surgery and at other important times.","quantity":"?"}],"name":"subject","doc":"Information about the animal or person from which the data was measured.","quantity":"?","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float","name":"x","doc":"x coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"y","doc":"y coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"z","doc":"z coordinate of the channel location.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"imp","doc":"Impedance of the channel.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"location","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","neurodata_type_inc":"VectorData"},{"dtype":"float","name":"filtering","doc":"Description of hardware filtering.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"group","doc":"Reference to the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"},{"dtype":"ascii","name":"group_name","doc":"Name of the ElectrodeGroup this electrode is a part of.","neurodata_type_inc":"VectorData"}],"name":"electrodes","doc":"A table of all electrodes (i.e. channels) used for recording.","quantity":"?","neurodata_type_inc":"DynamicTable"}],"name":"extracellular_ephys","doc":"Metadata related to extracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"name":"sweep_table","doc":"The table which groups different PatchClampSeries together.","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","name":"filtering","doc":"Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","quantity":"?"}],"name":"intracellular_ephys","doc":"Metadata related to intracellular electrophysiology.","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"name":"optogenetics","doc":"Metadata describing optogenetic stimuluation.","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"name":"optophysiology","doc":"Metadata related to optophysiology.","quantity":"?"}],"datasets":[{"dtype":"text","name":"data_collection","doc":"Notes about data collection and analysis.","quantity":"?"},{"dtype":"text","name":"experiment_description","doc":"General description of the experiment.","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","name":"experimenter","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","quantity":"?"},{"dtype":"text","name":"institution","doc":"Institution(s) where experiment was performed.","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","name":"keywords","doc":"Terms to search over.","quantity":"?"},{"dtype":"text","name":"lab","doc":"Laboratory where experiment was performed.","quantity":"?"},{"dtype":"text","name":"notes","doc":"Notes about the experiment.","quantity":"?"},{"dtype":"text","name":"pharmacology","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","quantity":"?"},{"dtype":"text","name":"protocol","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","name":"related_publications","doc":"Publication information. PMID, DOI, URL, etc.","quantity":"?"},{"dtype":"text","name":"session_id","doc":"Lab-specific ID for the session.","quantity":"?"},{"dtype":"text","name":"slices","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","quantity":"?"},{"dtype":"text","name":"source_script","doc":"Script file or link to public source code used to create this NWB file.","quantity":"?","attributes":[{"name":"file_name","doc":"Name of script file.","dtype":"text"}]},{"dtype":"text","name":"stimulus","doc":"Notes about stimuli, such as how and where they were presented.","quantity":"?"},{"dtype":"text","name":"surgery","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","quantity":"?"},{"dtype":"text","name":"virus","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","quantity":"?"}],"name":"general","doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them."},{"groups":[{"name":"epochs","doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"trials","doc":"Repeated experimental events that have a logical grouping.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"name":"invalid_times","doc":"Time intervals that should be removed from analysis.","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"name":"intervals","doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","quantity":"?"},{"name":"units","doc":"Data about sorted spike units.","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","name":"file_create_date","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array."},{"dtype":"text","name":"identifier","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files."},{"dtype":"text","name":"session_description","doc":"A description of the experimental session and data in the file."},{"dtype":"isodatetime","name":"session_start_time","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds."},{"dtype":"isodatetime","name":"timestamps_reference_time","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero)."}],"name":"root","doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"name":"nwb_version","doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","dtype":"text","value":"2.1.0"}]}]},1{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"Values of each feature at each time.","attributes":[{"name":"unit","doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"feature_units","doc":"Units of each feature.","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","name":"features","doc":"Description of the features represented in TimeSeries::data."}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","name":"data","doc":"Annotations made during an experiment.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","name":"data","doc":"Use values >0 if interval started, <0 if interval ended.","attributes":[{"name":"resolution","doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","dtype":"float","value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","dtype":"text","value":"n/a"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"datasets":[{"dtype":"text","name":"band_name","doc":"Name of the band, e.g. theta.","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float","name":"band_limits","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_mean","doc":"The mean Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float","name":"band_stdev","doc":"The standard deviation of Gaussian filters, in Hz.","neurodata_type_inc":"VectorData"}],"name":"bands","doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","name":"data","doc":"Data decomposed into frequency bands.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"no unit"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"metric","doc":"The metric used, e.g. phase, amplitude, power."}],"links":[{"name":"source_timeseries","doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"spike_times_index","doc":"Index into the spike_times dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"double","name":"spike_times","doc":"Spike times for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"obs_intervals_index","doc":"Index into the obs_intervals dataset.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"double","name":"obs_intervals","doc":"Observation intervals for each unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"electrodes_index","doc":"Index into electrodes.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"name":"electrodes","doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"name":"electrode_group","doc":"Electrode group that each spike unit came from.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_mean","doc":"Spike waveform mean for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float","name":"waveform_sd","doc":"Spike waveform standard deviation for each spike unit.","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]}{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","name":"data","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","required":false,"dtype":"text","default_value":"meters"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"text","name":"reference_frame","doc":"Description defining what exactly 'straight-ahead' means.","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]}~ {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Applied power for optogenetic stimulus, in watts.","attributes":[{"name":"unit","doc":"Unit of measurement for data, which is fixed to 'watts'.","dtype":"text","value":"watts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"links":[{"name":"site","doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of stimulation site."},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"text","name":"location","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."}],"links":[{"name":"device","doc":"Device that generated the stimulus.","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]}`4H'^4H'^5H'^SNOD8XxO(HHhPS(T5H'^(5H'^85H'^GCOLw4{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Recorded voltage data.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float","name":"channel_conversion","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","quantity":"?","attributes":[{"name":"axis","doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","dtype":"int","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","name":"data","doc":"Spike waveforms.","attributes":[{"name":"unit","doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","name":"timestamps","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","attributes":[{"name":"interval","doc":"Value is '1'","dtype":"int32","value":1},{"name":"unit","doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","name":"description","doc":"Description of features (eg, ''PC1'') for each of the extracted features."},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","name":"features","doc":"Multi-dimensional array of features extracted from each event."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of events that features correspond to (can be a link)."},{"name":"electrodes","doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","name":"detection_method","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values."},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"source_idx","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Timestamps of events, in seconds.","attributes":[{"name":"unit","doc":"Unit of measurement for event times, which is fixed to 'seconds'.","dtype":"text","value":"seconds"}]}],"links":[{"name":"source_electricalseries","doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries description or comments field.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"links":[{"name":"device","doc":"Link to the device that was used to record from this electrode group.","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"name":"description","doc":"Description of this electrode group.","dtype":"text"},{"name":"location","doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","dtype":"text"}]},{"datasets":[{"dtype":"text","name":"waveform_filtering","doc":"Filtering applied to data before generating mean/sd"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_mean","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","name":"waveform_sd","doc":"Stdev of waveforms for each cluster, using the same indices as in mean"}],"links":[{"name":"clustering_interface","doc":"Link to Clustering interface that was the source of the clustered data","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","name":"description","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)"},{"shape":[null],"dims":["num_events"],"dtype":"int32","name":"num","doc":"Cluster number of each event"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","name":"peak_over_rms","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric)."},{"shape":[null],"dims":["num_events"],"dtype":"float64","name":"times","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module."}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}B{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","name":"data","doc":"Recorded voltage or current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float","name":"gain","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","quantity":"?"}],"links":[{"name":"electrode","doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded voltage.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps.","quantity":"?"},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms.","quantity":"?"},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads.","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"float32","name":"bias_current","doc":"Bias current, in amps, fixed to 0.0."},{"dtype":"float32","name":"bridge_balance","doc":"Bridge balance, in ohms, fixed to 0.0."},{"dtype":"float32","name":"capacitance_compensation","doc":"Capacitance compensation, in farads, fixed to 0.0."}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus current applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Recorded current.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"amperes"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]},{"dtype":"float32","name":"capacitance_fast","doc":"Fast capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"capacitance_slow","doc":"Slow capacitance, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"resistance_comp_bandwidth","doc":"Resistance compensation bandwidth, in hertz.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","dtype":"text","value":"hertz"}]},{"dtype":"float32","name":"resistance_comp_correction","doc":"Resistance compensation correction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"resistance_comp_prediction","doc":"Resistance compensation prediction, in percent.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","dtype":"text","value":"percent"}]},{"dtype":"float32","name":"whole_cell_capacitance_comp","doc":"Whole cell capacitance compensation, in farads.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","dtype":"text","value":"farads"}]},{"dtype":"float32","name":"whole_cell_series_resistance_comp","doc":"Whole cell series resistance compensation, in ohms.","quantity":"?","attributes":[{"name":"unit","doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"name":"data","doc":"Stimulus voltage applied.","attributes":[{"name":"unit","doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text","value":"volts"},{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries","attributes":[{"name":"stimulus_description","doc":"Protocol/stimulus name for this patch-clamp dataset.","dtype":"text"},{"name":"sweep_number","doc":"Sweep number, allows to group different PatchClampSeries together.","required":false,"dtype":"uint64"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"dtype":"text","name":"description","doc":"Description of electrode (e.g., whole-cell, sharp, etc.)."},{"dtype":"text","name":"filtering","doc":"Electrode specific filtering.","quantity":"?"},{"dtype":"text","name":"initial_access_resistance","doc":"Initial access resistance.","quantity":"?"},{"dtype":"text","name":"location","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","quantity":"?"},{"dtype":"text","name":"resistance","doc":"Electrode resistance, in ohms.","quantity":"?"},{"dtype":"text","name":"seal","doc":"Information about seal used for recording.","quantity":"?"},{"dtype":"text","name":"slice","doc":"Information about slice used for recording.","quantity":"?"}],"links":[{"name":"device","doc":"Device that was used to record from this electrode.","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint64","name":"sweep_number","doc":"Sweep number of the PatchClampSeries in that row.","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"name":"series","doc":"The PatchClampSeries with the sweep number in that row.","neurodata_type_inc":"VectorData"},{"name":"series_index","doc":"Index for series.","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}]},{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":["width|height","width|height|depth"],"dtype":"float32","name":"field_of_view","doc":"Width, height and depth of image, or imaged area, in meters.","quantity":"?"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"name":"pmt_gain","doc":"Photomultiplier gain.","required":false,"dtype":"float32"},{"name":"scan_line_rate","doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","required":false,"dtype":"float32"},{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","name":"data","doc":"Signals from ROIs.","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","required":false,"dtype":"float32","default_value":1.0},{"name":"resolution","doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","required":false,"dtype":"float32","default_value":-1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","dtype":"text"}]},{"name":"rois","doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. Each row in data should correspond to the signal from one ROI. Each element on the second dimension of data should correspond to the signal from one ROI.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries","attributes":[{"name":"description","doc":"Description of the time series.","required":false,"dtype":"text","default_value":"no description"},{"name":"comments","doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"name":"reference_images","doc":"Image stacks that the segmentation masks apply to."}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"name":"image_mask","doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"pixel_mask_index","doc":"Index into pixel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float"}],"name":"pixel_mask","doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"name":"voxel_mask_index","doc":"Index into voxel_mask.","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float"}],"name":"voxel_mask","doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_rows"],"dtype":"int","name":"id","doc":"Array of unique identifiers for the rows of this dynamic table.","neurodata_type_inc":"ElementIdentifiers"},{"doc":"Vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorData"},{"doc":"Indices for the vector columns of this dynamic table.","quantity":"*","neurodata_type_inc":"VectorIndex"}],"links":[{"name":"imaging_plane","doc":"Link to ImagingPlane object from which this data was generated.","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation","attributes":[{"name":"colnames","doc":"The names of the columns in this table. This should be used to specify an order to the columns.","dtype":"ascii","shape":[null],"dims":["num_columns"]},{"name":"description","doc":"Description of what is in this dynamic table.","dtype":"text"}]}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"datasets":[{"dtype":"text","name":"description","doc":"Description or other notes about the channel."},{"dtype":"float","name":"emission_lambda","doc":"Emission wavelength for channel, in nm."}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"}],"datasets":[{"dtype":"text","name":"description","doc":"Description of the imaging plane.","quantity":"?"},{"dtype":"float","name":"excitation_lambda","doc":"Excitation wavelength, in nm."},{"dtype":"float","name":"imaging_rate","doc":"Rate that images are acquired, in Hz."},{"dtype":"text","name":"indicator","doc":"Calcium indicator."},{"dtype":"text","name":"location","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible."},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x|y|z"],["height","width","depth","x|y|z"]],"dtype":"float32","name":"manifold","doc":"Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space.","quantity":"?","attributes":[{"name":"conversion","doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","required":false,"dtype":"float","default_value":1.0},{"name":"unit","doc":"Base unit of measurement for working with the data. The default value is 'meters'.","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","name":"reference_frame","doc":"Describes position and reference frame of manifold based on position of first element in manifold. For example, text description of anatomical location or vectors needed to rotate to common anatomical axis (eg, AP/DV/ML). This field is necessary to interpret manifold. If manifold is not present then this field is not required.","quantity":"?"}],"links":[{"name":"device","doc":"Link to the Device object that was used to record from this electrode.","target_type":"Device"}],"doc":"An imaging plane and its metadata.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"groups":[{"groups":[{"name":"corrected","doc":"Image stack with frames shifted to the common coordinates.","neurodata_type_inc":"ImageSeries"},{"name":"xy_translation","doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","neurodata_type_inc":"TimeSeries"}],"links":[{"name":"original","doc":"Link to ImageSeries object that is being registered.","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"}]}{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_phase_map","doc":"Phase response to stimulus on the first measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row|column"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_1_power_map","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_phase_map","doc":"Phase response to stimulus on the second measured axis.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"axis_2_power_map","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","quantity":"?","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"unit","doc":"Unit that axis data is stored in (e.g., degrees).","dtype":"text"}]},{"shape":[2],"dims":["names"],"dtype":"text","name":"axis_descriptions","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta']."},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"focal_depth_image","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"focal_depth","doc":"Focal depth offset, in meters.","dtype":"float"},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","name":"sign_map","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","attributes":[{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","name":"vasculature_image","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","attributes":[{"name":"bits_per_pixel","doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","dtype":"int32"},{"name":"dimension","doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height,width.","dtype":"int32","shape":[null],"dims":["row_col"]},{"name":"field_of_view","doc":"Size of viewing area, in meters.","dtype":"float","shape":[null],"dims":["row_col"]},{"name":"format","doc":"Format of image. Right now only 'raw' is supported.","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}q{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.1.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}2././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.5.1_imageseries_no_data.nwb0000644000175100001730000051323014467767506023131 0ustar00runnerdockerHDF  ` ;TREEHAHEAP`x@ 0 .specloc<HhTREE HEAPX test_imageseries8SNOD Hh!!#P8<H88;TREE@ HEAPX0 external_fileformattimestamps(SNOD(Pp  6c H starting_frame@(SNOD0   GCOL external_fileexternalseconds no commentsno descriptioncore ImageSeries$08507de4-b293-43c9-ba0f-a14478c13b03 2022-09-01T22:48:52.260844+00:00 ADDME ADDME 2022-09-01T22:48:52.260631+00:00 2022-09-01T22:48:52.260631+00:002.3.0coreNWBFile$0563619a-697e-41f7-97a4-13aeb5667e61q{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"}],"groups":[{"doc":"An abstract data type for a group storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"groups":[{"doc":"Container objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Container"}],"datasets":[{"doc":"Data objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Data"}],"doc":"A simple Container for holding onto multiple containers.","data_type_inc":"Container","data_type_def":"SimpleMultiContainer"}]}N{"groups":[{"datasets":[{"shape":[null],"dims":["number of non-zero values"],"dtype":"uint","doc":"The column indices.","name":"indices"},{"shape":[null],"dims":["number of rows in the matrix + 1"],"dtype":"uint","doc":"The row index pointer.","name":"indptr"},{"shape":[null],"dims":["number of non-zero values"],"doc":"The non-zero values in the matrix.","name":"data"}],"doc":"A compressed sparse row matrix. Data are stored in the standard CSR format, where column indices for row i are stored in indices[indptr[i]:indptr[i+1]] and their corresponding values are stored in data[indptr[i]:indptr[i+1]].","data_type_inc":"Container","data_type_def":"CSRMatrix","attributes":[{"doc":"The shape (number of rows, number of columns) of this sparse matrix.","name":"shape","dtype":"uint","shape":[2],"dims":["number of rows, number of columns"]}]}]}Z{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"base"},{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.5.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"datasets":[{"dtype":"uint8","doc":"Data that come from a fixed set of values. A data value of i corresponds to the i-th value in the VectorData referenced by the 'elements' attribute.","data_type_inc":"VectorData","data_type_def":"EnumData","attributes":[{"doc":"Reference to the VectorData object that contains the enumerable elements","name":"elements","dtype":{"target_type":"VectorData","reftype":"object"}}]}]}%6c( ?@4 4%6c 8 interval@ @unit Pp H comments  H description  H namespace  Hneurodata_type  H object_id$ !#TREEHEAPX$P-$HEAPX$P/1P2p406P8 ?@@   q HSN Z  xXxXx@Xx.(6-(?(A(~(l9(@(l (I2(x((TREETREE4HEAPX(1presentationtemplates0TREEHEAPX4PSNOD(%P2p4P%06P8TREEHEAPXp8P8;TREEHEAPX0;P H nwb_version 0D8EXG%6cx%6c%6c%6cacquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODhH=(`$-$xX>h?<8EXG8%/1 C&6c H namespace  Hneurodata_type  H object_id$ PTREEJHEAPX8xGhdmf-commonhdmf-experimentalcore GJTREENHEAPX8J1.5.0HSNOD0hGGJ(nPnppL NTREEPHEAPX0@Nbasetablesparsenamespace(SNODKL N&6cSNODO ml8R &6cGCOL{"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["dim0"],["dim0","dim1"],["dim0","dim1","dim2"],["dim0","dim1","dim2","dim3"]],"doc":"An n-dimensional dataset representing a column of a DynamicTable. If used without an accompanying VectorIndex, first dimension is along the rows of the DynamicTable and each step along the first dimension is a cell of the larger table. VectorData can also be used to represent a ragged array if paired with a VectorIndex. This allows for storing arrays of varying length in a single cell of the DynamicTable by indexing into this VectorData. The first vector is at VectorData[0:VectorIndex[0]]. The second vector is at VectorData[VectorIndex[0]:VectorIndex[1]], and so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"doc":"Description of what these vectors represent.","name":"description","dtype":"text"}]},{"shape":[null],"dims":["num_rows"],"dtype":"uint8","doc":"Used with VectorData to encode a ragged array. An array of indices into the first dimension of the target VectorData, and forming a map between the rows of a DynamicTable and the indices of the VectorData. The name of the VectorIndex is expected to be the name of the target VectorData object followed by \"_index\".","data_type_inc":"VectorData","data_type_def":"VectorIndex","attributes":[{"doc":"Reference to the target dataset that this index applies to.","name":"target","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"DynamicTableRegion provides a link from one table to an index or region of another. The `table` attribute is a link to another `DynamicTable`, indicating which table is referenced, and the data is int(s) indicating the row(s) (0-indexed) of the target array. `DynamicTableRegion`s can be used to associate rows with repeated meta-data without data duplication. They can also be used to create hierarchical relationships between multiple `DynamicTable`s. `DynamicTableRegion` objects may be paired with a `VectorIndex` object to create ragged references, so a single cell of a `DynamicTable` can reference many rows of another `DynamicTable`.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"doc":"Reference to the DynamicTable object that this region applies to.","name":"table","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"doc":"Description of what this table region points to.","name":"description","dtype":"text"}]}],"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"Array of unique identifiers for the rows of this dynamic table.","name":"id","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns, including index columns, of this dynamic table.","quantity":"*","data_type_inc":"VectorData"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). These datasets represent different columns in the table. Apart from a column that contains unique identifiers for each row, there are no other required datasets. Users are free to add any number of custom VectorData objects (columns) here. DynamicTable also supports ragged array columns, where each element can be of a different size. To add a ragged array column, use a VectorIndex type to index the corresponding VectorData type. See documentation for VectorData and VectorIndex for more details. Unlike a compound data type, which is analogous to storing an array-of-structs, a DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"doc":"The names of the columns in this table. This should be used to specify an order to the columns.","name":"colnames","dtype":"text","shape":[null],"dims":["num_columns"]},{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text"}]},{"groups":[{"doc":"A DynamicTable representing a particular category for columns in the AlignedDynamicTable parent container. The table MUST be aligned with (i.e., have the same number of rows) as all other DynamicTables stored in the AlignedDynamicTable parent container. The name of the category is given by the name of the DynamicTable and its description by the description attribute of the DynamicTable.","quantity":"*","data_type_inc":"DynamicTable"}],"doc":"DynamicTable container that supports storing a collection of sub-tables. Each sub-table is a DynamicTable itself that is aligned with the main table by row index. I.e., all DynamicTables stored in this group MUST have the same number of rows. This type effectively defines a 2-level table in which the main data is stored in the main table implemented by this type and additional columns of the table are grouped into categories, with each category being represented by a separate DynamicTable stored within the group.","data_type_inc":"DynamicTable","data_type_def":"AlignedDynamicTable","attributes":[{"doc":"The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.","name":"categories","dtype":"text","shape":[null],"dims":["num_categories"]}]}]}0&6c@&6cPnppTREEsHEAPXp0.1.0Hq0sTREEvHEAPX8Psexperimentalresourcesnamespace SNODpq0sP&6cSNODt(XHw`&6cGCOLx{"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The user term that maps to one or more resources in the 'resources' table.","name":"key","dtype":"text"}],"doc":"A table for storing user terms that are used to refer to external resources.","name":"keys","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the key in the 'keys' table.","name":"keys_idx","dtype":"uint"},{"doc":"The index into the 'resources' table","name":"resources_idx","dtype":"uint"},{"doc":"The unique identifier entity.","name":"entity_id","dtype":"text"},{"doc":"The URI for the entity this reference applies to. This can be an empty string.","name":"entity_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"entities","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The name of the resource.","name":"resource","dtype":"text"},{"doc":"The URI for the resource. This can be an empty string.","name":"resource_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"resources","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The UUID for the object.","name":"object_id","dtype":"text"},{"doc":"The field of the object. This can be an empty string if the object is a dataset and the field is the dataset values.","name":"field","dtype":"text"}],"doc":"A table for identifying which objects in a file contain references to external resources.","name":"objects","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the 'objects' table for the object that holds the key.","name":"objects_idx","dtype":"uint"},{"doc":"The index to the 'keys' table for the key.","name":"keys_idx","dtype":"uint"}],"doc":"A table for identifying which objects use which keys.","name":"object_keys","data_type_inc":"Data"}],"doc":"A set of four tables for tracking external resource references in a file. NOTE: this data type is in beta testing and is subject to change in a later version.","data_type_inc":"Container","data_type_def":"ExternalResources"}]}{"namespaces":[{"doc":"Experimental data structures provided by HDMF. These are not guaranteed to be available in the future","schema":[{"namespace":"hdmf-common"},{"source":"experimental"},{"source":"resources"}],"name":"hdmf-experimental","full_name":"HDMF Experimental","version":"0.1.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"groups":[{"doc":"Metadata about a data acquisition device, e.g., recording system, electrode, microscope.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"doc":"Description of the device (e.g., model, firmware version, processing software version, etc.) as free-form text.","name":"description","required":false,"dtype":"text"},{"doc":"The name of the manufacturer of the device.","name":"manufacturer","required":false,"dtype":"text"}]}]}p&6cTREEHEAPXЋ2.3.0HPpTREE(xXHEAP`SNOD(Pp&6cGCOL{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["x","y"],["x","y","r, g, b"],["x","y","r, g, b, a"]],"dtype":"numeric","doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"doc":"Pixel resolution of the image, in pixels per centimeter.","name":"resolution","required":false,"dtype":"float32"},{"doc":"Description of the image.","name":"description","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","name":"sync","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float64","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","name":"starting_time","quantity":"?","attributes":[{"doc":"Sampling rate, in Hz.","name":"rate","dtype":"float32"},{"doc":"Unit of measurement for time, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","name":"timestamps","quantity":"?","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","name":"control","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","name":"control_description","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"doc":"Description of the time series.","name":"description","required":false,"dtype":"text","default_value":"no description"},{"doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","name":"comments","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"doc":"Description of this collection of processed data.","name":"description","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A collection of images.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"doc":"Description of this collection of images.","name":"description","dtype":"text"}]}]}SNOD0h(px8&6c&6c&6c&6c&6cnwb.basenwb.devicenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOL.{"groups":[{"datasets":[{"dtype":"float32","doc":"Start time of epoch, in seconds.","name":"start_time","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Stop time of epoch, in seconds.","name":"stop_time","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"User-defined tags that identify or categorize events.","name":"tags","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for tags.","name":"tags_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to.","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"doc":"An index into a TimeSeries object.","name":"timeseries","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for timeseries.","name":"timeseries_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals"}]}6-{"datasets":[{"shape":[null,null],"dims":["x","y"],"dtype":"numeric","doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage"},{"shape":[null,null,3],"dims":["x","y","r, g, b"],"dtype":"numeric","doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage"},{"shape":[null,null,4],"dims":["x","y","r, g, b, a"],"dtype":"numeric","doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage"}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","x","y"],["frame","x","y","z"]],"dtype":"numeric","doc":"Binary data representing images across frames.","name":"data","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","doc":"Number of pixels on x, y, (and z) axes.","name":"dimension","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","name":"external_file","quantity":"?","attributes":[{"doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","name":"starting_frame","dtype":"int32","shape":[null],"dims":["num_files"]}]},{"dtype":"text","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","name":"format","quantity":"?","default_value":"raw"}],"links":[{"doc":"Link to the Device object that was used to capture these images.","name":"device","target_type":"Device","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][x][y] or [frame][x][y][z].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries"},{"links":[{"doc":"Link to ImageSeries object that this image mask is applied to.","name":"masked_imageseries","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries"},{"datasets":[{"dtype":"float32","doc":"Distance from camera/monitor to target/eye.","name":"distance","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"},{"shape":[[null,null,null],[null,null,null,3]],"dims":[["frame","x","y"],["frame","x","y","r, g, b"]],"dtype":"numeric","doc":"Images presented to subject, either grayscale or RGB","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","name":"orientation","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int32","doc":"Index of the frame in the referenced ImageSeries.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to ImageSeries object containing images that are indexed.","name":"indexed_timeseries","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries"}]}?{"datasets":[{"doc":"Any one-off datasets","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"doc":"Any notes the user has about the dataset being stored","name":"notes","dtype":"text"}]}],"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.","name":"acquisition"},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.","name":"analysis"},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"ScratchData"}],"doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","name":"scratch","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.","name":"processing"},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Stimuli presented during the experiment.","name":"presentation"},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.","name":"templates"}],"doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file.","name":"stimulus"},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"LabMetaData"},{"groups":[{"doc":"Data acquisition devices.","quantity":"*","neurodata_type_inc":"Device"}],"doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","name":"devices","quantity":"?"},{"doc":"Information about the animal or person from which the data was measured.","name":"subject","quantity":"?","neurodata_type_inc":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float32","doc":"x coordinate of the channel location in the brain (+x is posterior).","name":"x","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate of the channel location in the brain (+y is inferior).","name":"y","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate of the channel location in the brain (+z is right).","name":"z","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Impedance of the channel, in ohms.","name":"imp","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Description of hardware filtering, including the filter name and frequency cutoffs.","name":"filtering","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Reference to the ElectrodeGroup this electrode is a part of.","name":"group","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Name of the ElectrodeGroup this electrode is a part of.","name":"group_name","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"x coordinate in electrode group","name":"rel_x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate in electrode group","name":"rel_y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate in electrode group","name":"rel_z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of the reference used for this electrode.","name":"reference","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"A table of all electrodes (i.e. channels) used for recording.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTable"}],"doc":"Metadata related to extracellular electrophysiology.","name":"extracellular_ephys","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"doc":"The table which groups different PatchClampSeries together.","name":"sweep_table","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","doc":"Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","name":"filtering","quantity":"?"}],"doc":"Metadata related to intracellular electrophysiology.","name":"intracellular_ephys","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"doc":"Metadata describing optogenetic stimuluation.","name":"optogenetics","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"doc":"Metadata related to optophysiology.","name":"optophysiology","quantity":"?"}],"datasets":[{"dtype":"text","doc":"Notes about data collection and analysis.","name":"data_collection","quantity":"?"},{"dtype":"text","doc":"General description of the experiment.","name":"experiment_description","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","name":"experimenter","quantity":"?"},{"dtype":"text","doc":"Institution(s) where experiment was performed.","name":"institution","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","doc":"Terms to search over.","name":"keywords","quantity":"?"},{"dtype":"text","doc":"Laboratory where experiment was performed.","name":"lab","quantity":"?"},{"dtype":"text","doc":"Notes about the experiment.","name":"notes","quantity":"?"},{"dtype":"text","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","name":"pharmacology","quantity":"?"},{"dtype":"text","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","name":"protocol","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","doc":"Publication information. PMID, DOI, URL, etc.","name":"related_publications","quantity":"?"},{"dtype":"text","doc":"Lab-specific ID for the session.","name":"session_id","quantity":"?"},{"dtype":"text","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","name":"slices","quantity":"?"},{"dtype":"text","doc":"Script file or link to public source code used to create this NWB file.","name":"source_script","quantity":"?","attributes":[{"doc":"Name of script file.","name":"file_name","dtype":"text"}]},{"dtype":"text","doc":"Notes about stimuli, such as how and where they were presented.","name":"stimulus","quantity":"?"},{"dtype":"text","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","name":"surgery","quantity":"?"},{"dtype":"text","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","name":"virus","quantity":"?"}],"doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them.","name":"general"},{"groups":[{"doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","name":"epochs","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Repeated experimental events that have a logical grouping.","name":"trials","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Time intervals that should be removed from analysis.","name":"invalid_times","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","name":"intervals","quantity":"?"},{"doc":"Data about sorted spike units.","name":"units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array.","name":"file_create_date"},{"dtype":"text","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files.","name":"identifier"},{"dtype":"text","doc":"A description of the experimental session and data in the file.","name":"session_description"},{"dtype":"isodatetime","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds.","name":"session_start_time"},{"dtype":"isodatetime","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).","name":"timestamps_reference_time"}],"doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","name":"root","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","name":"nwb_version","dtype":"text","value":"2.3.0"}]},{"doc":"Lab-specific meta-data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"datasets":[{"dtype":"text","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","name":"age","quantity":"?"},{"dtype":"isodatetime","doc":"Date of birth of subject. Can be supplied instead of 'age'.","name":"date_of_birth","quantity":"?"},{"dtype":"text","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","name":"description","quantity":"?"},{"dtype":"text","doc":"Genetic strain. If absent, assume Wild Type (WT).","name":"genotype","quantity":"?"},{"dtype":"text","doc":"Gender of subject.","name":"sex","quantity":"?"},{"dtype":"text","doc":"Species of subject.","name":"species","quantity":"?"},{"dtype":"text","doc":"Strain of subject.","name":"strain","quantity":"?"},{"dtype":"text","doc":"ID of animal/person used/participating in experiment (lab convention).","name":"subject_id","quantity":"?"},{"dtype":"text","doc":"Weight at time of experiment, at time of surgery and at other important times.","name":"weight","quantity":"?"}],"doc":"Information about the animal or person from which the data was measured.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"}]}A{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"Values of each feature at each time.","name":"data","attributes":[{"doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","name":"unit","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Units of each feature.","name":"feature_units","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of the features represented in TimeSeries::data.","name":"features"}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","doc":"Annotations made during an experiment.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","doc":"Use values >0 if interval started, <0 if interval ended.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries"},{"groups":[{"datasets":[{"dtype":"text","doc":"Name of the band, e.g. theta.","name":"band_name","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float32","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","name":"band_limits","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The mean Gaussian filters, in Hz.","name":"band_mean","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The standard deviation of Gaussian filters, in Hz.","name":"band_stdev","neurodata_type_inc":"VectorData"}],"doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","name":"bands","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","doc":"Data decomposed into frequency bands.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"no unit"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"The metric used, e.g. phase, amplitude, power.","name":"metric"},{"doc":"DynamicTableRegion pointer to the channels that this decomposition series was generated from.","name":"source_channels","quantity":"?","neurodata_type_inc":"DynamicTableRegion"}],"links":[{"doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","name":"source_timeseries","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries"},{"datasets":[{"doc":"Index into the spike_times dataset.","name":"spike_times_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"float64","doc":"Spike times for each unit.","name":"spike_times","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"The smallest possible difference between two spike times. Usually 1 divided by the acquisition sampling rate from which spike times were extracted, but could be larger if the acquisition time series was downsampled or smaller if the acquisition time series was smoothed/interpolated and it is possible for the spike time to be between samples.","name":"resolution","required":false,"dtype":"float64"}]},{"doc":"Index into the obs_intervals dataset.","name":"obs_intervals_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"float64","doc":"Observation intervals for each unit.","name":"obs_intervals","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into electrodes.","name":"electrodes_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Electrode group that each spike unit came from.","name":"electrode_group","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform mean for each spike unit.","name":"waveform_mean","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform standard deviation for each spike unit.","name":"waveform_sd","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[null,null],"dims":["num_waveforms","num_samples"],"dtype":"numeric","doc":"Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.","name":"waveforms","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"doc":"Index into the waveforms dataset. One value for every spike event. See 'waveforms' for more detail.","name":"waveforms_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Index into the waveforms_index dataset. One value for every unit (row in the table). See 'waveforms' for more detail.","name":"waveforms_index_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units"}]}~{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"meters"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description defining what exactly 'straight-ahead' means.","name":"reference_frame","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries"},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]}l {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Applied power for optogenetic stimulus, in watts.","name":"data","attributes":[{"doc":"Unit of measurement for data, which is fixed to 'watts'.","name":"unit","dtype":"text","value":"watts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","name":"site","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries"},{"datasets":[{"dtype":"text","doc":"Description of stimulation site.","name":"description"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"text","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"}],"links":[{"doc":"Device that generated the stimulus.","name":"device","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]} &6c&6c'6cSNOD(HH8X'6c '6c0'6cGCOL`l9{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","doc":"Recorded voltage data.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float32","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","name":"channel_conversion","quantity":"?","attributes":[{"doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","name":"axis","dtype":"int32","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"doc":"Filtering applied to all channels of the data. For example, if this ElectricalSeries represents high-pass-filtered data (also known as AP Band), then this value could be \"High-pass 4-pole Bessel filter at 500 Hz\". If this ElectricalSeries represents low-pass-filtered LFP data and the type of filter is unknown, then this value could be \"Low-pass filter at 300 Hz\". If a non-standard filter type is used, provide as much detail about the filter properties as possible.","name":"filtering","required":false,"dtype":"text"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","doc":"Spike waveforms.","name":"data","attributes":[{"doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","name":"timestamps","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries"},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of features (eg, ''PC1'') for each of the extracted features.","name":"description"},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","doc":"Multi-dimensional array of features extracted from each event.","name":"features"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of events that features correspond to (can be a link).","name":"times"},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values.","name":"detection_method"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data.","name":"source_idx"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Timestamps of events, in seconds.","name":"times","attributes":[{"doc":"Unit of measurement for event times, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"links":[{"doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","name":"source_electricalseries","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"datasets":[{"dtype":[{"doc":"x coordinate","name":"x","dtype":"float32"},{"doc":"y coordinate","name":"y","dtype":"float32"},{"doc":"z coordinate","name":"z","dtype":"float32"}],"doc":"stereotaxic or common framework coordinates","name":"position","quantity":"?"}],"links":[{"doc":"Link to the device that was used to record from this electrode group.","name":"device","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"doc":"Description of this electrode group.","name":"description","dtype":"text"},{"doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, etc. Use standard atlas names for anatomical regions when possible.","name":"location","dtype":"text"}]},{"datasets":[{"dtype":"text","doc":"Filtering applied to data before generating mean/sd","name":"waveform_filtering"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)","name":"waveform_mean"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"Stdev of waveforms for each cluster, using the same indices as in mean","name":"waveform_sd"}],"links":[{"doc":"Link to Clustering interface that was the source of the clustered data","name":"clustering_interface","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)","name":"description"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Cluster number of each event","name":"num"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric).","name":"peak_over_rms"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module.","name":"times"}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}@{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Recorded voltage or current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","name":"gain","quantity":"?"}],"links":[{"doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","name":"electrode","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"doc":"Protocol/stimulus name for this patch-clamp dataset.","name":"stimulus_description","dtype":"text"},{"doc":"Sweep number, allows to group different PatchClampSeries together.","name":"sweep_number","required":false,"dtype":"uint32"}]},{"datasets":[{"doc":"Recorded voltage.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Bias current, in amps.","name":"bias_current","quantity":"?"},{"dtype":"float32","doc":"Bridge balance, in ohms.","name":"bridge_balance","quantity":"?"},{"dtype":"float32","doc":"Capacitance compensation, in farads.","name":"capacitance_compensation","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries"},{"datasets":[{"dtype":"float32","doc":"Bias current, in amps, fixed to 0.0.","name":"bias_current"},{"dtype":"float32","doc":"Bridge balance, in ohms, fixed to 0.0.","name":"bridge_balance"},{"dtype":"float32","doc":"Capacitance compensation, in farads, fixed to 0.0.","name":"capacitance_compensation"}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"doc":"An IZeroClampSeries has no stimulus, so this attribute is automatically set to \"N/A\"","name":"stimulus_description","dtype":"text","value":"N/A"}]},{"datasets":[{"doc":"Stimulus current applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries"},{"datasets":[{"doc":"Recorded current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Fast capacitance, in farads.","name":"capacitance_fast","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Slow capacitance, in farads.","name":"capacitance_slow","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Resistance compensation bandwidth, in hertz.","name":"resistance_comp_bandwidth","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","name":"unit","dtype":"text","value":"hertz"}]},{"dtype":"float32","doc":"Resistance compensation correction, in percent.","name":"resistance_comp_correction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Resistance compensation prediction, in percent.","name":"resistance_comp_prediction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Whole cell capacitance compensation, in farads.","name":"whole_cell_capacitance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Whole cell series resistance compensation, in ohms.","name":"whole_cell_series_resistance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","name":"unit","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries"},{"datasets":[{"doc":"Stimulus voltage applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries"},{"datasets":[{"dtype":"text","doc":"Description of electrode (e.g., whole-cell, sharp, etc.).","name":"description"},{"dtype":"text","doc":"Electrode specific filtering.","name":"filtering","quantity":"?"},{"dtype":"text","doc":"Initial access resistance.","name":"initial_access_resistance","quantity":"?"},{"dtype":"text","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","quantity":"?"},{"dtype":"text","doc":"Electrode resistance, in ohms.","name":"resistance","quantity":"?"},{"dtype":"text","doc":"Information about seal used for recording.","name":"seal","quantity":"?"},{"dtype":"text","doc":"Information about slice used for recording.","name":"slice","quantity":"?"}],"links":[{"doc":"Device that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint32","doc":"Sweep number of the PatchClampSeries in that row.","name":"sweep_number","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"doc":"The PatchClampSeries with the sweep number in that row.","name":"series","neurodata_type_inc":"VectorData"},{"doc":"Index for series.","name":"series_index","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable"}]}I2{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"}],"links":[{"doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"doc":"Photomultiplier gain.","name":"pmt_gain","required":false,"dtype":"float32"},{"doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","name":"scan_line_rate","required":false,"dtype":"float32"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","doc":"Signals from ROIs.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","name":"rois","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. The first dimension represents time. The second dimension, if present, represents ROIs.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries"},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"PlaneSegmentation"}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"doc":"Image stacks that the segmentation masks apply to.","name":"reference_images"}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","name":"image_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into pixel_mask.","name":"pixel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float32"}],"doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"pixel_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into voxel_mask.","name":"voxel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint32"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float32"}],"doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"voxel_mask","quantity":"?","neurodata_type_inc":"VectorData"}],"links":[{"doc":"Link to ImagingPlane object from which this data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation"},{"groups":[{"doc":"An optical channel used to record from an imaging plane.","quantity":"+","neurodata_type_inc":"OpticalChannel"}],"datasets":[{"dtype":"text","doc":"Description of the imaging plane.","name":"description","quantity":"?"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"float32","doc":"Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead.","name":"imaging_rate","quantity":"?"},{"dtype":"text","doc":"Calcium indicator.","name":"indicator"},{"dtype":"text","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x, y, z"],["height","width","depth","x, y, z"]],"dtype":"float32","doc":"DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing.","name":"manifold","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Base unit of measurement for working with the data. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma).","name":"origin_coords","quantity":"?","attributes":[{"doc":"Measurement units for origin_coords. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid.","name":"grid_spacing","quantity":"?","attributes":[{"doc":"Measurement units for grid_spacing. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","doc":"Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = \"Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral).\"","name":"reference_frame","quantity":"?"}],"links":[{"doc":"Link to the Device object that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An imaging plane and its metadata.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"datasets":[{"dtype":"text","doc":"Description or other notes about the channel.","name":"description"},{"dtype":"float32","doc":"Emission wavelength for channel, in nm.","name":"emission_lambda"}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"},{"groups":[{"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"},{"groups":[{"doc":"Image stack with frames shifted to the common coordinates.","name":"corrected","neurodata_type_inc":"ImageSeries"},{"doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","name":"xy_translation","neurodata_type_inc":"TimeSeries"}],"links":[{"doc":"Link to ImageSeries object that is being registered.","name":"original","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}]}x{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the first measured axis.","name":"axis_1_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_1_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the second measured axis.","name":"axis_2_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_2_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[2],"dims":["axis_1, axis_2"],"dtype":"text","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta'].","name":"axis_descriptions"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","name":"focal_depth_image","quantity":"?","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Focal depth offset, in meters.","name":"focal_depth","dtype":"float32"},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","name":"sign_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","name":"vasculature_image","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. This group does not store the raw responses imaged during retinotopic mapping or the stimuli presented, but rather the resulting phase and power maps after applying a Fourier transform on the averaged responses. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.device"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.3.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}.@'6c././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.5.1_imageseries_no_unit.nwb0000644000175100001730000051270014467767506023200 0ustar00runnerdockerHDF  ` :TREEHAHEAP`? 0 .specloc0;HhTREE HEAPX test_imageseries8SNOD Hh(P`;H788: TREE@ HEAPX datatimestamps8SNOD(Pp  8 ?@4 4 6c @ conversion ?@4 4?`SNOD0 ????????????????????????????@@    qpRNZxwwhw.P6-P?PAP~Pl9P@Pl PI2PxPP @ resolution ?@4 4( ?@4 4`6c 8 interval@ @unitPp H comments  H description H namespace Hneurodata_type  H object_id$(TREEHEAPXHP-HEAPXP/hHEAPX(presentationtemplates01HEAPX(PGCOLseconds no commentsno descriptioncore ImageSeries$5440d733-e78e-4fc1-b53e-91e058d26036 2022-09-01T22:48:52.786684+00:00ADDME ADDME 2022-09-01T22:48:52.786474+00:00 2022-09-01T22:48:52.786474+00:00 2.3.0 coreNWBFile$b6dca617-836b-4772-90f3-122867c8a80aq{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"}],"groups":[{"doc":"An abstract data type for a group storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"groups":[{"doc":"Container objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Container"}],"datasets":[{"doc":"Data objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Data"}],"doc":"A simple Container for holding onto multiple containers.","data_type_inc":"Container","data_type_def":"SimpleMultiContainer"}]}N{"groups":[{"datasets":[{"shape":[null],"dims":["number of non-zero values"],"dtype":"uint","doc":"The column indices.","name":"indices"},{"shape":[null],"dims":["number of rows in the matrix + 1"],"dtype":"uint","doc":"The row index pointer.","name":"indptr"},{"shape":[null],"dims":["number of non-zero values"],"doc":"The non-zero values in the matrix.","name":"data"}],"doc":"A compressed sparse row matrix. Data are stored in the standard CSR format, where column indices for row i are stored in indices[indptr[i]:indptr[i+1]] and their corresponding values are stored in data[indptr[i]:indptr[i+1]].","data_type_inc":"Container","data_type_def":"CSRMatrix","attributes":[{"doc":"The shape (number of rows, number of columns) of this sparse matrix.","name":"shape","dtype":"uint","shape":[2],"dims":["number of rows, number of columns"]}]}]}Z{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"base"},{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.5.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"datasets":[{"dtype":"uint8","doc":"Data that come from a fixed set of values. A data value of i corresponds to the i-th value in the VectorData referenced by the 'elements' attribute.","data_type_inc":"VectorData","data_type_def":"EnumData","attributes":[{"doc":"Reference to the VectorData object that contains the enumerable elements","name":"elements","dtype":{"target_type":"VectorData","reftype":"object"}}]}]}TREETREE3TREESNOD105X5x7X5x7TREEHEAPX7P88:TREEHEAPXX:P H nwb_version XC`DFx6cx6c6c6cacquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODhp<(-x=>0;`DF8@/hHB6c H namespace Hneurodata_type H object_id$PTREEIHEAPX8Fhdmf-commonhdmf-experimentalcore  G@ITREEMHEAPX`I1.5.0HSNOD0؊F G@IPmxmo(KHMTREEPHEAPX0hMbasetablesparsenamespace(SNODK(KHM6cSNODO @l0k`Q6cGCOL{"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["dim0"],["dim0","dim1"],["dim0","dim1","dim2"],["dim0","dim1","dim2","dim3"]],"doc":"An n-dimensional dataset representing a column of a DynamicTable. If used without an accompanying VectorIndex, first dimension is along the rows of the DynamicTable and each step along the first dimension is a cell of the larger table. VectorData can also be used to represent a ragged array if paired with a VectorIndex. This allows for storing arrays of varying length in a single cell of the DynamicTable by indexing into this VectorData. The first vector is at VectorData[0:VectorIndex[0]]. The second vector is at VectorData[VectorIndex[0]:VectorIndex[1]], and so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"doc":"Description of what these vectors represent.","name":"description","dtype":"text"}]},{"shape":[null],"dims":["num_rows"],"dtype":"uint8","doc":"Used with VectorData to encode a ragged array. An array of indices into the first dimension of the target VectorData, and forming a map between the rows of a DynamicTable and the indices of the VectorData. The name of the VectorIndex is expected to be the name of the target VectorData object followed by \"_index\".","data_type_inc":"VectorData","data_type_def":"VectorIndex","attributes":[{"doc":"Reference to the target dataset that this index applies to.","name":"target","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"DynamicTableRegion provides a link from one table to an index or region of another. The `table` attribute is a link to another `DynamicTable`, indicating which table is referenced, and the data is int(s) indicating the row(s) (0-indexed) of the target array. `DynamicTableRegion`s can be used to associate rows with repeated meta-data without data duplication. They can also be used to create hierarchical relationships between multiple `DynamicTable`s. `DynamicTableRegion` objects may be paired with a `VectorIndex` object to create ragged references, so a single cell of a `DynamicTable` can reference many rows of another `DynamicTable`.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"doc":"Reference to the DynamicTable object that this region applies to.","name":"table","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"doc":"Description of what this table region points to.","name":"description","dtype":"text"}]}],"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"Array of unique identifiers for the rows of this dynamic table.","name":"id","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns, including index columns, of this dynamic table.","quantity":"*","data_type_inc":"VectorData"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). These datasets represent different columns in the table. Apart from a column that contains unique identifiers for each row, there are no other required datasets. Users are free to add any number of custom VectorData objects (columns) here. DynamicTable also supports ragged array columns, where each element can be of a different size. To add a ragged array column, use a VectorIndex type to index the corresponding VectorData type. See documentation for VectorData and VectorIndex for more details. Unlike a compound data type, which is analogous to storing an array-of-structs, a DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"doc":"The names of the columns in this table. This should be used to specify an order to the columns.","name":"colnames","dtype":"text","shape":[null],"dims":["num_columns"]},{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text"}]},{"groups":[{"doc":"A DynamicTable representing a particular category for columns in the AlignedDynamicTable parent container. The table MUST be aligned with (i.e., have the same number of rows) as all other DynamicTables stored in the AlignedDynamicTable parent container. The name of the category is given by the name of the DynamicTable and its description by the description attribute of the DynamicTable.","quantity":"*","data_type_inc":"DynamicTable"}],"doc":"DynamicTable container that supports storing a collection of sub-tables. Each sub-table is a DynamicTable itself that is aligned with the main table by row index. I.e., all DynamicTables stored in this group MUST have the same number of rows. This type effectively defines a 2-level table in which the main data is stored in the main table implemented by this type and additional columns of the table are grouped into categories, with each category being represented by a separate DynamicTable stored within the group.","data_type_inc":"DynamicTable","data_type_def":"AlignedDynamicTable","attributes":[{"doc":"The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.","name":"categories","dtype":"text","shape":[null],"dims":["num_categories"]}]}]}6c6cxmoTREErHEAPXo0.1.0H8pXrTREE(uHEAPX8xrexperimentalresourcesnamespace SNODp8pXr6cSNODt(pv6cGCOLx{"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The user term that maps to one or more resources in the 'resources' table.","name":"key","dtype":"text"}],"doc":"A table for storing user terms that are used to refer to external resources.","name":"keys","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the key in the 'keys' table.","name":"keys_idx","dtype":"uint"},{"doc":"The index into the 'resources' table","name":"resources_idx","dtype":"uint"},{"doc":"The unique identifier entity.","name":"entity_id","dtype":"text"},{"doc":"The URI for the entity this reference applies to. This can be an empty string.","name":"entity_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"entities","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The name of the resource.","name":"resource","dtype":"text"},{"doc":"The URI for the resource. This can be an empty string.","name":"resource_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"resources","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The UUID for the object.","name":"object_id","dtype":"text"},{"doc":"The field of the object. This can be an empty string if the object is a dataset and the field is the dataset values.","name":"field","dtype":"text"}],"doc":"A table for identifying which objects in a file contain references to external resources.","name":"objects","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the 'objects' table for the object that holds the key.","name":"objects_idx","dtype":"uint"},{"doc":"The index to the 'keys' table for the key.","name":"keys_idx","dtype":"uint"}],"doc":"A table for identifying which objects use which keys.","name":"object_keys","data_type_inc":"Data"}],"doc":"A set of four tables for tracking external resource references in a file. NOTE: this data type is in beta testing and is subject to change in a later version.","data_type_inc":"Container","data_type_def":"ExternalResources"}]}{"namespaces":[{"doc":"Experimental data structures provided by HDMF. These are not guaranteed to be available in the future","schema":[{"namespace":"hdmf-common"},{"source":"experimental"},{"source":"resources"}],"name":"hdmf-experimental","full_name":"HDMF Experimental","version":"0.1.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"groups":[{"doc":"Metadata about a data acquisition device, e.g., recording system, electrode, microscope.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"doc":"Description of the device (e.g., model, firmware version, processing software version, etc.) as free-form text.","name":"description","required":false,"dtype":"text"},{"doc":"The name of the manufacturer of the device.","name":"manufacturer","required":false,"dtype":"text"}]}]}(6c؊TREEHEAPX2.3.0HxTREEPxHEAP`SNODPx86cGCOL{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["x","y"],["x","y","r, g, b"],["x","y","r, g, b, a"]],"dtype":"numeric","doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"doc":"Pixel resolution of the image, in pixels per centimeter.","name":"resolution","required":false,"dtype":"float32"},{"doc":"Description of the image.","name":"description","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","name":"sync","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float64","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","name":"starting_time","quantity":"?","attributes":[{"doc":"Sampling rate, in Hz.","name":"rate","dtype":"float32"},{"doc":"Unit of measurement for time, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","name":"timestamps","quantity":"?","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","name":"control","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","name":"control_description","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"doc":"Description of the time series.","name":"description","required":false,"dtype":"text","default_value":"no description"},{"doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","name":"comments","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"doc":"Description of this collection of processed data.","name":"description","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A collection of images.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"doc":"Description of this collection of images.","name":"description","dtype":"text"}]}]}SNODXhPx`H6cX6ch6cx6c6cnwb.basenwb.devicenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOL.{"groups":[{"datasets":[{"dtype":"float32","doc":"Start time of epoch, in seconds.","name":"start_time","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Stop time of epoch, in seconds.","name":"stop_time","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"User-defined tags that identify or categorize events.","name":"tags","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for tags.","name":"tags_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to.","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"doc":"An index into a TimeSeries object.","name":"timeseries","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for timeseries.","name":"timeseries_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals"}]}6-{"datasets":[{"shape":[null,null],"dims":["x","y"],"dtype":"numeric","doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage"},{"shape":[null,null,3],"dims":["x","y","r, g, b"],"dtype":"numeric","doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage"},{"shape":[null,null,4],"dims":["x","y","r, g, b, a"],"dtype":"numeric","doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage"}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","x","y"],["frame","x","y","z"]],"dtype":"numeric","doc":"Binary data representing images across frames.","name":"data","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","doc":"Number of pixels on x, y, (and z) axes.","name":"dimension","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","name":"external_file","quantity":"?","attributes":[{"doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","name":"starting_frame","dtype":"int32","shape":[null],"dims":["num_files"]}]},{"dtype":"text","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","name":"format","quantity":"?","default_value":"raw"}],"links":[{"doc":"Link to the Device object that was used to capture these images.","name":"device","target_type":"Device","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][x][y] or [frame][x][y][z].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries"},{"links":[{"doc":"Link to ImageSeries object that this image mask is applied to.","name":"masked_imageseries","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries"},{"datasets":[{"dtype":"float32","doc":"Distance from camera/monitor to target/eye.","name":"distance","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"},{"shape":[[null,null,null],[null,null,null,3]],"dims":[["frame","x","y"],["frame","x","y","r, g, b"]],"dtype":"numeric","doc":"Images presented to subject, either grayscale or RGB","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","name":"orientation","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int32","doc":"Index of the frame in the referenced ImageSeries.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to ImageSeries object containing images that are indexed.","name":"indexed_timeseries","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries"}]}?{"datasets":[{"doc":"Any one-off datasets","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"doc":"Any notes the user has about the dataset being stored","name":"notes","dtype":"text"}]}],"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.","name":"acquisition"},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.","name":"analysis"},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"ScratchData"}],"doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","name":"scratch","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.","name":"processing"},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Stimuli presented during the experiment.","name":"presentation"},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.","name":"templates"}],"doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file.","name":"stimulus"},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"LabMetaData"},{"groups":[{"doc":"Data acquisition devices.","quantity":"*","neurodata_type_inc":"Device"}],"doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","name":"devices","quantity":"?"},{"doc":"Information about the animal or person from which the data was measured.","name":"subject","quantity":"?","neurodata_type_inc":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float32","doc":"x coordinate of the channel location in the brain (+x is posterior).","name":"x","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate of the channel location in the brain (+y is inferior).","name":"y","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate of the channel location in the brain (+z is right).","name":"z","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Impedance of the channel, in ohms.","name":"imp","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Description of hardware filtering, including the filter name and frequency cutoffs.","name":"filtering","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Reference to the ElectrodeGroup this electrode is a part of.","name":"group","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Name of the ElectrodeGroup this electrode is a part of.","name":"group_name","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"x coordinate in electrode group","name":"rel_x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate in electrode group","name":"rel_y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate in electrode group","name":"rel_z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of the reference used for this electrode.","name":"reference","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"A table of all electrodes (i.e. channels) used for recording.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTable"}],"doc":"Metadata related to extracellular electrophysiology.","name":"extracellular_ephys","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"doc":"The table which groups different PatchClampSeries together.","name":"sweep_table","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","doc":"Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","name":"filtering","quantity":"?"}],"doc":"Metadata related to intracellular electrophysiology.","name":"intracellular_ephys","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"doc":"Metadata describing optogenetic stimuluation.","name":"optogenetics","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"doc":"Metadata related to optophysiology.","name":"optophysiology","quantity":"?"}],"datasets":[{"dtype":"text","doc":"Notes about data collection and analysis.","name":"data_collection","quantity":"?"},{"dtype":"text","doc":"General description of the experiment.","name":"experiment_description","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","name":"experimenter","quantity":"?"},{"dtype":"text","doc":"Institution(s) where experiment was performed.","name":"institution","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","doc":"Terms to search over.","name":"keywords","quantity":"?"},{"dtype":"text","doc":"Laboratory where experiment was performed.","name":"lab","quantity":"?"},{"dtype":"text","doc":"Notes about the experiment.","name":"notes","quantity":"?"},{"dtype":"text","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","name":"pharmacology","quantity":"?"},{"dtype":"text","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","name":"protocol","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","doc":"Publication information. PMID, DOI, URL, etc.","name":"related_publications","quantity":"?"},{"dtype":"text","doc":"Lab-specific ID for the session.","name":"session_id","quantity":"?"},{"dtype":"text","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","name":"slices","quantity":"?"},{"dtype":"text","doc":"Script file or link to public source code used to create this NWB file.","name":"source_script","quantity":"?","attributes":[{"doc":"Name of script file.","name":"file_name","dtype":"text"}]},{"dtype":"text","doc":"Notes about stimuli, such as how and where they were presented.","name":"stimulus","quantity":"?"},{"dtype":"text","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","name":"surgery","quantity":"?"},{"dtype":"text","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","name":"virus","quantity":"?"}],"doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them.","name":"general"},{"groups":[{"doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","name":"epochs","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Repeated experimental events that have a logical grouping.","name":"trials","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Time intervals that should be removed from analysis.","name":"invalid_times","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","name":"intervals","quantity":"?"},{"doc":"Data about sorted spike units.","name":"units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array.","name":"file_create_date"},{"dtype":"text","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files.","name":"identifier"},{"dtype":"text","doc":"A description of the experimental session and data in the file.","name":"session_description"},{"dtype":"isodatetime","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds.","name":"session_start_time"},{"dtype":"isodatetime","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).","name":"timestamps_reference_time"}],"doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","name":"root","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","name":"nwb_version","dtype":"text","value":"2.3.0"}]},{"doc":"Lab-specific meta-data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"datasets":[{"dtype":"text","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","name":"age","quantity":"?"},{"dtype":"isodatetime","doc":"Date of birth of subject. Can be supplied instead of 'age'.","name":"date_of_birth","quantity":"?"},{"dtype":"text","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","name":"description","quantity":"?"},{"dtype":"text","doc":"Genetic strain. If absent, assume Wild Type (WT).","name":"genotype","quantity":"?"},{"dtype":"text","doc":"Gender of subject.","name":"sex","quantity":"?"},{"dtype":"text","doc":"Species of subject.","name":"species","quantity":"?"},{"dtype":"text","doc":"Strain of subject.","name":"strain","quantity":"?"},{"dtype":"text","doc":"ID of animal/person used/participating in experiment (lab convention).","name":"subject_id","quantity":"?"},{"dtype":"text","doc":"Weight at time of experiment, at time of surgery and at other important times.","name":"weight","quantity":"?"}],"doc":"Information about the animal or person from which the data was measured.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"}]}A{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"Values of each feature at each time.","name":"data","attributes":[{"doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","name":"unit","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Units of each feature.","name":"feature_units","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of the features represented in TimeSeries::data.","name":"features"}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","doc":"Annotations made during an experiment.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","doc":"Use values >0 if interval started, <0 if interval ended.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries"},{"groups":[{"datasets":[{"dtype":"text","doc":"Name of the band, e.g. theta.","name":"band_name","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float32","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","name":"band_limits","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The mean Gaussian filters, in Hz.","name":"band_mean","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The standard deviation of Gaussian filters, in Hz.","name":"band_stdev","neurodata_type_inc":"VectorData"}],"doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","name":"bands","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","doc":"Data decomposed into frequency bands.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"no unit"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"The metric used, e.g. phase, amplitude, power.","name":"metric"},{"doc":"DynamicTableRegion pointer to the channels that this decomposition series was generated from.","name":"source_channels","quantity":"?","neurodata_type_inc":"DynamicTableRegion"}],"links":[{"doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","name":"source_timeseries","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries"},{"datasets":[{"doc":"Index into the spike_times dataset.","name":"spike_times_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"float64","doc":"Spike times for each unit.","name":"spike_times","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"The smallest possible difference between two spike times. Usually 1 divided by the acquisition sampling rate from which spike times were extracted, but could be larger if the acquisition time series was downsampled or smaller if the acquisition time series was smoothed/interpolated and it is possible for the spike time to be between samples.","name":"resolution","required":false,"dtype":"float64"}]},{"doc":"Index into the obs_intervals dataset.","name":"obs_intervals_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"float64","doc":"Observation intervals for each unit.","name":"obs_intervals","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into electrodes.","name":"electrodes_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Electrode group that each spike unit came from.","name":"electrode_group","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform mean for each spike unit.","name":"waveform_mean","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform standard deviation for each spike unit.","name":"waveform_sd","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[null,null],"dims":["num_waveforms","num_samples"],"dtype":"numeric","doc":"Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.","name":"waveforms","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"doc":"Index into the waveforms dataset. One value for every spike event. See 'waveforms' for more detail.","name":"waveforms_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Index into the waveforms_index dataset. One value for every unit (row in the table). See 'waveforms' for more detail.","name":"waveforms_index_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units"}]}~{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"meters"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description defining what exactly 'straight-ahead' means.","name":"reference_frame","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries"},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]}l {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Applied power for optogenetic stimulus, in watts.","name":"data","attributes":[{"doc":"Unit of measurement for data, which is fixed to 'watts'.","name":"unit","dtype":"text","value":"watts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","name":"site","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries"},{"datasets":[{"dtype":"text","doc":"Description of stimulation site.","name":"description"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"text","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"}],"links":[{"doc":"Device that generated the stimulus.","name":"device","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]} 6c6c6cSNOD(Hȯp8XذȜ؝6c6c6cGCOL`l9{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","doc":"Recorded voltage data.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float32","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","name":"channel_conversion","quantity":"?","attributes":[{"doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","name":"axis","dtype":"int32","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"doc":"Filtering applied to all channels of the data. For example, if this ElectricalSeries represents high-pass-filtered data (also known as AP Band), then this value could be \"High-pass 4-pole Bessel filter at 500 Hz\". If this ElectricalSeries represents low-pass-filtered LFP data and the type of filter is unknown, then this value could be \"Low-pass filter at 300 Hz\". If a non-standard filter type is used, provide as much detail about the filter properties as possible.","name":"filtering","required":false,"dtype":"text"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","doc":"Spike waveforms.","name":"data","attributes":[{"doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","name":"timestamps","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries"},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of features (eg, ''PC1'') for each of the extracted features.","name":"description"},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","doc":"Multi-dimensional array of features extracted from each event.","name":"features"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of events that features correspond to (can be a link).","name":"times"},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values.","name":"detection_method"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data.","name":"source_idx"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Timestamps of events, in seconds.","name":"times","attributes":[{"doc":"Unit of measurement for event times, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"links":[{"doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","name":"source_electricalseries","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"datasets":[{"dtype":[{"doc":"x coordinate","name":"x","dtype":"float32"},{"doc":"y coordinate","name":"y","dtype":"float32"},{"doc":"z coordinate","name":"z","dtype":"float32"}],"doc":"stereotaxic or common framework coordinates","name":"position","quantity":"?"}],"links":[{"doc":"Link to the device that was used to record from this electrode group.","name":"device","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"doc":"Description of this electrode group.","name":"description","dtype":"text"},{"doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, etc. Use standard atlas names for anatomical regions when possible.","name":"location","dtype":"text"}]},{"datasets":[{"dtype":"text","doc":"Filtering applied to data before generating mean/sd","name":"waveform_filtering"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)","name":"waveform_mean"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"Stdev of waveforms for each cluster, using the same indices as in mean","name":"waveform_sd"}],"links":[{"doc":"Link to Clustering interface that was the source of the clustered data","name":"clustering_interface","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)","name":"description"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Cluster number of each event","name":"num"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric).","name":"peak_over_rms"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module.","name":"times"}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}@{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Recorded voltage or current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","name":"gain","quantity":"?"}],"links":[{"doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","name":"electrode","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"doc":"Protocol/stimulus name for this patch-clamp dataset.","name":"stimulus_description","dtype":"text"},{"doc":"Sweep number, allows to group different PatchClampSeries together.","name":"sweep_number","required":false,"dtype":"uint32"}]},{"datasets":[{"doc":"Recorded voltage.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Bias current, in amps.","name":"bias_current","quantity":"?"},{"dtype":"float32","doc":"Bridge balance, in ohms.","name":"bridge_balance","quantity":"?"},{"dtype":"float32","doc":"Capacitance compensation, in farads.","name":"capacitance_compensation","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries"},{"datasets":[{"dtype":"float32","doc":"Bias current, in amps, fixed to 0.0.","name":"bias_current"},{"dtype":"float32","doc":"Bridge balance, in ohms, fixed to 0.0.","name":"bridge_balance"},{"dtype":"float32","doc":"Capacitance compensation, in farads, fixed to 0.0.","name":"capacitance_compensation"}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"doc":"An IZeroClampSeries has no stimulus, so this attribute is automatically set to \"N/A\"","name":"stimulus_description","dtype":"text","value":"N/A"}]},{"datasets":[{"doc":"Stimulus current applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries"},{"datasets":[{"doc":"Recorded current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Fast capacitance, in farads.","name":"capacitance_fast","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Slow capacitance, in farads.","name":"capacitance_slow","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Resistance compensation bandwidth, in hertz.","name":"resistance_comp_bandwidth","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","name":"unit","dtype":"text","value":"hertz"}]},{"dtype":"float32","doc":"Resistance compensation correction, in percent.","name":"resistance_comp_correction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Resistance compensation prediction, in percent.","name":"resistance_comp_prediction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Whole cell capacitance compensation, in farads.","name":"whole_cell_capacitance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Whole cell series resistance compensation, in ohms.","name":"whole_cell_series_resistance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","name":"unit","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries"},{"datasets":[{"doc":"Stimulus voltage applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries"},{"datasets":[{"dtype":"text","doc":"Description of electrode (e.g., whole-cell, sharp, etc.).","name":"description"},{"dtype":"text","doc":"Electrode specific filtering.","name":"filtering","quantity":"?"},{"dtype":"text","doc":"Initial access resistance.","name":"initial_access_resistance","quantity":"?"},{"dtype":"text","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","quantity":"?"},{"dtype":"text","doc":"Electrode resistance, in ohms.","name":"resistance","quantity":"?"},{"dtype":"text","doc":"Information about seal used for recording.","name":"seal","quantity":"?"},{"dtype":"text","doc":"Information about slice used for recording.","name":"slice","quantity":"?"}],"links":[{"doc":"Device that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint32","doc":"Sweep number of the PatchClampSeries in that row.","name":"sweep_number","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"doc":"The PatchClampSeries with the sweep number in that row.","name":"series","neurodata_type_inc":"VectorData"},{"doc":"Index for series.","name":"series_index","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable"}]}I2{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"}],"links":[{"doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"doc":"Photomultiplier gain.","name":"pmt_gain","required":false,"dtype":"float32"},{"doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","name":"scan_line_rate","required":false,"dtype":"float32"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","doc":"Signals from ROIs.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","name":"rois","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. The first dimension represents time. The second dimension, if present, represents ROIs.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries"},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"PlaneSegmentation"}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"doc":"Image stacks that the segmentation masks apply to.","name":"reference_images"}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","name":"image_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into pixel_mask.","name":"pixel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float32"}],"doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"pixel_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into voxel_mask.","name":"voxel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint32"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float32"}],"doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"voxel_mask","quantity":"?","neurodata_type_inc":"VectorData"}],"links":[{"doc":"Link to ImagingPlane object from which this data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation"},{"groups":[{"doc":"An optical channel used to record from an imaging plane.","quantity":"+","neurodata_type_inc":"OpticalChannel"}],"datasets":[{"dtype":"text","doc":"Description of the imaging plane.","name":"description","quantity":"?"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"float32","doc":"Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead.","name":"imaging_rate","quantity":"?"},{"dtype":"text","doc":"Calcium indicator.","name":"indicator"},{"dtype":"text","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x, y, z"],["height","width","depth","x, y, z"]],"dtype":"float32","doc":"DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing.","name":"manifold","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Base unit of measurement for working with the data. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma).","name":"origin_coords","quantity":"?","attributes":[{"doc":"Measurement units for origin_coords. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid.","name":"grid_spacing","quantity":"?","attributes":[{"doc":"Measurement units for grid_spacing. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","doc":"Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = \"Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral).\"","name":"reference_frame","quantity":"?"}],"links":[{"doc":"Link to the Device object that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An imaging plane and its metadata.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"datasets":[{"dtype":"text","doc":"Description or other notes about the channel.","name":"description"},{"dtype":"float32","doc":"Emission wavelength for channel, in nm.","name":"emission_lambda"}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"},{"groups":[{"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"},{"groups":[{"doc":"Image stack with frames shifted to the common coordinates.","name":"corrected","neurodata_type_inc":"ImageSeries"},{"doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","name":"xy_translation","neurodata_type_inc":"TimeSeries"}],"links":[{"doc":"Link to ImageSeries object that is being registered.","name":"original","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}]}x{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the first measured axis.","name":"axis_1_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_1_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the second measured axis.","name":"axis_2_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_2_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[2],"dims":["axis_1, axis_2"],"dtype":"text","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta'].","name":"axis_descriptions"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","name":"focal_depth_image","quantity":"?","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Focal depth offset, in meters.","name":"focal_depth","dtype":"float32"},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","name":"sign_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","name":"vasculature_image","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. This group does not store the raw responses imaged during retinotopic mapping or the stimuli presented, but rather the resulting phase and power maps after applying a Fourier transform on the averaged responses. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.device"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.3.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}.6c././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.5.1_timeseries_no_data.nwb0000644000175100001730000051224014467767506023005 0ustar00runnerdockerHDF  ` 9TREEH?HEAP`> 0 .specloc:HhTREE HEAPXtest_timeseries@SNOD HhP@:H69TREE@HEAPX starting_time@SNOD(Pp   ?@4 4@ a*c 8rate ?@4 4?h0 @@@ @ @ q@PQN@Z@@x`v`vH`v.06-0?0A0~0l90@0l 0I20x00SNOD0 @unit@Pp H comments @ H description@ H namespace@ Hneurodata_type @ H object_id$@TREEHEAPXP@,HEAPXP`.8HEAPX(Xpresentationtemplates002`4669GCOLseconds no commentsno descriptioncore TimeSeries$3254e320-72a3-4172-b3b8-74f5c6813cee 2022-09-01T03:43:29.343410+00:00ADDME ADDME 2022-09-01T03:43:29.343129+00:00 2022-09-01T03:43:29.343129+00:00 2.3.0 coreNWBFile$a0a85d60-5fa7-4557-af13-b72e6cd477f2q{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"}],"groups":[{"doc":"An abstract data type for a group storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"groups":[{"doc":"Container objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Container"}],"datasets":[{"doc":"Data objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Data"}],"doc":"A simple Container for holding onto multiple containers.","data_type_inc":"Container","data_type_def":"SimpleMultiContainer"}]}N{"groups":[{"datasets":[{"shape":[null],"dims":["number of non-zero values"],"dtype":"uint","doc":"The column indices.","name":"indices"},{"shape":[null],"dims":["number of rows in the matrix + 1"],"dtype":"uint","doc":"The row index pointer.","name":"indptr"},{"shape":[null],"dims":["number of non-zero values"],"doc":"The non-zero values in the matrix.","name":"data"}],"doc":"A compressed sparse row matrix. Data are stored in the standard CSR format, where column indices for row i are stored in indices[indptr[i]:indptr[i+1]] and their corresponding values are stored in data[indptr[i]:indptr[i+1]].","data_type_inc":"Container","data_type_def":"CSRMatrix","attributes":[{"doc":"The shape (number of rows, number of columns) of this sparse matrix.","name":"shape","dtype":"uint","shape":[2],"dims":["number of rows, number of columns"]}]}]}Z{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"base"},{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.5.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"datasets":[{"dtype":"uint8","doc":"Data that come from a fixed set of values. A data value of i corresponds to the i-th value in the VectorData referenced by the 'elements' attribute.","data_type_inc":"VectorData","data_type_def":"EnumData","attributes":[{"doc":"Reference to the VectorData object that contains the enumerable elements","name":"elements","dtype":{"target_type":"VectorData","reftype":"object"}}]}]}TREETREE3TREEHEAPX2PSNOD02`46TREEHEAPX6PTREEHEAPX89P H nwb_version@ 8B@C`EH a*cxX a*ch a*cx a*cacquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODhP;(p@,x`<p=:@C`E8`.8(A a*c H namespace@ Hneurodata_type@ H object_id$@PTREEHHEAPX8Ehdmf-commonhdmf-experimentalcore F HTREELHEAPX@H1.5.0HSNOD0pEF H0lXlxnJ(LTREENHEAPX0HLbasetablesparsenamespace(SNODIJ(L a*cSNODM kj@P a*cGCOL{"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["dim0"],["dim0","dim1"],["dim0","dim1","dim2"],["dim0","dim1","dim2","dim3"]],"doc":"An n-dimensional dataset representing a column of a DynamicTable. If used without an accompanying VectorIndex, first dimension is along the rows of the DynamicTable and each step along the first dimension is a cell of the larger table. VectorData can also be used to represent a ragged array if paired with a VectorIndex. This allows for storing arrays of varying length in a single cell of the DynamicTable by indexing into this VectorData. The first vector is at VectorData[0:VectorIndex[0]]. The second vector is at VectorData[VectorIndex[0]:VectorIndex[1]], and so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"doc":"Description of what these vectors represent.","name":"description","dtype":"text"}]},{"shape":[null],"dims":["num_rows"],"dtype":"uint8","doc":"Used with VectorData to encode a ragged array. An array of indices into the first dimension of the target VectorData, and forming a map between the rows of a DynamicTable and the indices of the VectorData. The name of the VectorIndex is expected to be the name of the target VectorData object followed by \"_index\".","data_type_inc":"VectorData","data_type_def":"VectorIndex","attributes":[{"doc":"Reference to the target dataset that this index applies to.","name":"target","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"DynamicTableRegion provides a link from one table to an index or region of another. The `table` attribute is a link to another `DynamicTable`, indicating which table is referenced, and the data is int(s) indicating the row(s) (0-indexed) of the target array. `DynamicTableRegion`s can be used to associate rows with repeated meta-data without data duplication. They can also be used to create hierarchical relationships between multiple `DynamicTable`s. `DynamicTableRegion` objects may be paired with a `VectorIndex` object to create ragged references, so a single cell of a `DynamicTable` can reference many rows of another `DynamicTable`.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"doc":"Reference to the DynamicTable object that this region applies to.","name":"table","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"doc":"Description of what this table region points to.","name":"description","dtype":"text"}]}],"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"Array of unique identifiers for the rows of this dynamic table.","name":"id","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns, including index columns, of this dynamic table.","quantity":"*","data_type_inc":"VectorData"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). These datasets represent different columns in the table. Apart from a column that contains unique identifiers for each row, there are no other required datasets. Users are free to add any number of custom VectorData objects (columns) here. DynamicTable also supports ragged array columns, where each element can be of a different size. To add a ragged array column, use a VectorIndex type to index the corresponding VectorData type. See documentation for VectorData and VectorIndex for more details. Unlike a compound data type, which is analogous to storing an array-of-structs, a DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"doc":"The names of the columns in this table. This should be used to specify an order to the columns.","name":"colnames","dtype":"text","shape":[null],"dims":["num_columns"]},{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text"}]},{"groups":[{"doc":"A DynamicTable representing a particular category for columns in the AlignedDynamicTable parent container. The table MUST be aligned with (i.e., have the same number of rows) as all other DynamicTables stored in the AlignedDynamicTable parent container. The name of the category is given by the name of the DynamicTable and its description by the description attribute of the DynamicTable.","quantity":"*","data_type_inc":"DynamicTable"}],"doc":"DynamicTable container that supports storing a collection of sub-tables. Each sub-table is a DynamicTable itself that is aligned with the main table by row index. I.e., all DynamicTables stored in this group MUST have the same number of rows. This type effectively defines a 2-level table in which the main data is stored in the main table implemented by this type and additional columns of the table are grouped into categories, with each category being represented by a separate DynamicTable stored within the group.","data_type_inc":"DynamicTable","data_type_def":"AlignedDynamicTable","attributes":[{"doc":"The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.","name":"categories","dtype":"text","shape":[null],"dims":["num_categories"]}]}]} a*c a*cXlxnTREEqHEAPXn0.1.0Ho8qTREEtHEAPX8Xqexperimentalresourcesnamespace SNODno8q a*cSNODr(`Pu a*cGCOLx{"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The user term that maps to one or more resources in the 'resources' table.","name":"key","dtype":"text"}],"doc":"A table for storing user terms that are used to refer to external resources.","name":"keys","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the key in the 'keys' table.","name":"keys_idx","dtype":"uint"},{"doc":"The index into the 'resources' table","name":"resources_idx","dtype":"uint"},{"doc":"The unique identifier entity.","name":"entity_id","dtype":"text"},{"doc":"The URI for the entity this reference applies to. This can be an empty string.","name":"entity_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"entities","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The name of the resource.","name":"resource","dtype":"text"},{"doc":"The URI for the resource. This can be an empty string.","name":"resource_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"resources","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The UUID for the object.","name":"object_id","dtype":"text"},{"doc":"The field of the object. This can be an empty string if the object is a dataset and the field is the dataset values.","name":"field","dtype":"text"}],"doc":"A table for identifying which objects in a file contain references to external resources.","name":"objects","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the 'objects' table for the object that holds the key.","name":"objects_idx","dtype":"uint"},{"doc":"The index to the 'keys' table for the key.","name":"keys_idx","dtype":"uint"}],"doc":"A table for identifying which objects use which keys.","name":"object_keys","data_type_inc":"Data"}],"doc":"A set of four tables for tracking external resource references in a file. NOTE: this data type is in beta testing and is subject to change in a later version.","data_type_inc":"Container","data_type_def":"ExternalResources"}]}{"namespaces":[{"doc":"Experimental data structures provided by HDMF. These are not guaranteed to be available in the future","schema":[{"namespace":"hdmf-common"},{"source":"experimental"},{"source":"resources"}],"name":"hdmf-experimental","full_name":"HDMF Experimental","version":"0.1.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"groups":[{"doc":"Metadata about a data acquisition device, e.g., recording system, electrode, microscope.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"doc":"Description of the device (e.g., model, firmware version, processing software version, etc.) as free-form text.","name":"description","required":false,"dtype":"text"},{"doc":"The name of the manufacturer of the device.","name":"manufacturer","required":false,"dtype":"text"}]}]} a*cTREEHEAPX؉2.3.0HXxTREE0x`HEAP`ȰSNOD0Xx a*cGCOL{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["x","y"],["x","y","r, g, b"],["x","y","r, g, b, a"]],"dtype":"numeric","doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"doc":"Pixel resolution of the image, in pixels per centimeter.","name":"resolution","required":false,"dtype":"float32"},{"doc":"Description of the image.","name":"description","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","name":"sync","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float64","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","name":"starting_time","quantity":"?","attributes":[{"doc":"Sampling rate, in Hz.","name":"rate","dtype":"float32"},{"doc":"Unit of measurement for time, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","name":"timestamps","quantity":"?","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","name":"control","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","name":"control_description","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"doc":"Description of the time series.","name":"description","required":false,"dtype":"text","default_value":"no description"},{"doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","name":"comments","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"doc":"Description of this collection of processed data.","name":"description","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A collection of images.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"doc":"Description of this collection of images.","name":"description","dtype":"text"}]}]}SNOD8h0xx@ a*c( a*c8 a*cH a*cX a*cnwb.basenwb.devicenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOL.{"groups":[{"datasets":[{"dtype":"float32","doc":"Start time of epoch, in seconds.","name":"start_time","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Stop time of epoch, in seconds.","name":"stop_time","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"User-defined tags that identify or categorize events.","name":"tags","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for tags.","name":"tags_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to.","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"doc":"An index into a TimeSeries object.","name":"timeseries","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for timeseries.","name":"timeseries_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals"}]}6-{"datasets":[{"shape":[null,null],"dims":["x","y"],"dtype":"numeric","doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage"},{"shape":[null,null,3],"dims":["x","y","r, g, b"],"dtype":"numeric","doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage"},{"shape":[null,null,4],"dims":["x","y","r, g, b, a"],"dtype":"numeric","doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage"}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","x","y"],["frame","x","y","z"]],"dtype":"numeric","doc":"Binary data representing images across frames.","name":"data","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","doc":"Number of pixels on x, y, (and z) axes.","name":"dimension","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","name":"external_file","quantity":"?","attributes":[{"doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","name":"starting_frame","dtype":"int32","shape":[null],"dims":["num_files"]}]},{"dtype":"text","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","name":"format","quantity":"?","default_value":"raw"}],"links":[{"doc":"Link to the Device object that was used to capture these images.","name":"device","target_type":"Device","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][x][y] or [frame][x][y][z].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries"},{"links":[{"doc":"Link to ImageSeries object that this image mask is applied to.","name":"masked_imageseries","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries"},{"datasets":[{"dtype":"float32","doc":"Distance from camera/monitor to target/eye.","name":"distance","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"},{"shape":[[null,null,null],[null,null,null,3]],"dims":[["frame","x","y"],["frame","x","y","r, g, b"]],"dtype":"numeric","doc":"Images presented to subject, either grayscale or RGB","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","name":"orientation","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int32","doc":"Index of the frame in the referenced ImageSeries.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to ImageSeries object containing images that are indexed.","name":"indexed_timeseries","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries"}]}?{"datasets":[{"doc":"Any one-off datasets","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"doc":"Any notes the user has about the dataset being stored","name":"notes","dtype":"text"}]}],"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.","name":"acquisition"},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.","name":"analysis"},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"ScratchData"}],"doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","name":"scratch","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.","name":"processing"},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Stimuli presented during the experiment.","name":"presentation"},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.","name":"templates"}],"doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file.","name":"stimulus"},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"LabMetaData"},{"groups":[{"doc":"Data acquisition devices.","quantity":"*","neurodata_type_inc":"Device"}],"doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","name":"devices","quantity":"?"},{"doc":"Information about the animal or person from which the data was measured.","name":"subject","quantity":"?","neurodata_type_inc":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float32","doc":"x coordinate of the channel location in the brain (+x is posterior).","name":"x","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate of the channel location in the brain (+y is inferior).","name":"y","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate of the channel location in the brain (+z is right).","name":"z","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Impedance of the channel, in ohms.","name":"imp","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Description of hardware filtering, including the filter name and frequency cutoffs.","name":"filtering","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Reference to the ElectrodeGroup this electrode is a part of.","name":"group","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Name of the ElectrodeGroup this electrode is a part of.","name":"group_name","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"x coordinate in electrode group","name":"rel_x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate in electrode group","name":"rel_y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate in electrode group","name":"rel_z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of the reference used for this electrode.","name":"reference","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"A table of all electrodes (i.e. channels) used for recording.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTable"}],"doc":"Metadata related to extracellular electrophysiology.","name":"extracellular_ephys","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"doc":"The table which groups different PatchClampSeries together.","name":"sweep_table","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","doc":"Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","name":"filtering","quantity":"?"}],"doc":"Metadata related to intracellular electrophysiology.","name":"intracellular_ephys","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"doc":"Metadata describing optogenetic stimuluation.","name":"optogenetics","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"doc":"Metadata related to optophysiology.","name":"optophysiology","quantity":"?"}],"datasets":[{"dtype":"text","doc":"Notes about data collection and analysis.","name":"data_collection","quantity":"?"},{"dtype":"text","doc":"General description of the experiment.","name":"experiment_description","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","name":"experimenter","quantity":"?"},{"dtype":"text","doc":"Institution(s) where experiment was performed.","name":"institution","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","doc":"Terms to search over.","name":"keywords","quantity":"?"},{"dtype":"text","doc":"Laboratory where experiment was performed.","name":"lab","quantity":"?"},{"dtype":"text","doc":"Notes about the experiment.","name":"notes","quantity":"?"},{"dtype":"text","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","name":"pharmacology","quantity":"?"},{"dtype":"text","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","name":"protocol","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","doc":"Publication information. PMID, DOI, URL, etc.","name":"related_publications","quantity":"?"},{"dtype":"text","doc":"Lab-specific ID for the session.","name":"session_id","quantity":"?"},{"dtype":"text","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","name":"slices","quantity":"?"},{"dtype":"text","doc":"Script file or link to public source code used to create this NWB file.","name":"source_script","quantity":"?","attributes":[{"doc":"Name of script file.","name":"file_name","dtype":"text"}]},{"dtype":"text","doc":"Notes about stimuli, such as how and where they were presented.","name":"stimulus","quantity":"?"},{"dtype":"text","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","name":"surgery","quantity":"?"},{"dtype":"text","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","name":"virus","quantity":"?"}],"doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them.","name":"general"},{"groups":[{"doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","name":"epochs","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Repeated experimental events that have a logical grouping.","name":"trials","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Time intervals that should be removed from analysis.","name":"invalid_times","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","name":"intervals","quantity":"?"},{"doc":"Data about sorted spike units.","name":"units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array.","name":"file_create_date"},{"dtype":"text","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files.","name":"identifier"},{"dtype":"text","doc":"A description of the experimental session and data in the file.","name":"session_description"},{"dtype":"isodatetime","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds.","name":"session_start_time"},{"dtype":"isodatetime","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).","name":"timestamps_reference_time"}],"doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","name":"root","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","name":"nwb_version","dtype":"text","value":"2.3.0"}]},{"doc":"Lab-specific meta-data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"datasets":[{"dtype":"text","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","name":"age","quantity":"?"},{"dtype":"isodatetime","doc":"Date of birth of subject. Can be supplied instead of 'age'.","name":"date_of_birth","quantity":"?"},{"dtype":"text","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","name":"description","quantity":"?"},{"dtype":"text","doc":"Genetic strain. If absent, assume Wild Type (WT).","name":"genotype","quantity":"?"},{"dtype":"text","doc":"Gender of subject.","name":"sex","quantity":"?"},{"dtype":"text","doc":"Species of subject.","name":"species","quantity":"?"},{"dtype":"text","doc":"Strain of subject.","name":"strain","quantity":"?"},{"dtype":"text","doc":"ID of animal/person used/participating in experiment (lab convention).","name":"subject_id","quantity":"?"},{"dtype":"text","doc":"Weight at time of experiment, at time of surgery and at other important times.","name":"weight","quantity":"?"}],"doc":"Information about the animal or person from which the data was measured.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"}]}A{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"Values of each feature at each time.","name":"data","attributes":[{"doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","name":"unit","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Units of each feature.","name":"feature_units","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of the features represented in TimeSeries::data.","name":"features"}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","doc":"Annotations made during an experiment.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","doc":"Use values >0 if interval started, <0 if interval ended.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries"},{"groups":[{"datasets":[{"dtype":"text","doc":"Name of the band, e.g. theta.","name":"band_name","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float32","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","name":"band_limits","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The mean Gaussian filters, in Hz.","name":"band_mean","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The standard deviation of Gaussian filters, in Hz.","name":"band_stdev","neurodata_type_inc":"VectorData"}],"doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","name":"bands","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","doc":"Data decomposed into frequency bands.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"no unit"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"The metric used, e.g. phase, amplitude, power.","name":"metric"},{"doc":"DynamicTableRegion pointer to the channels that this decomposition series was generated from.","name":"source_channels","quantity":"?","neurodata_type_inc":"DynamicTableRegion"}],"links":[{"doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","name":"source_timeseries","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries"},{"datasets":[{"doc":"Index into the spike_times dataset.","name":"spike_times_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"float64","doc":"Spike times for each unit.","name":"spike_times","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"The smallest possible difference between two spike times. Usually 1 divided by the acquisition sampling rate from which spike times were extracted, but could be larger if the acquisition time series was downsampled or smaller if the acquisition time series was smoothed/interpolated and it is possible for the spike time to be between samples.","name":"resolution","required":false,"dtype":"float64"}]},{"doc":"Index into the obs_intervals dataset.","name":"obs_intervals_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"float64","doc":"Observation intervals for each unit.","name":"obs_intervals","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into electrodes.","name":"electrodes_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Electrode group that each spike unit came from.","name":"electrode_group","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform mean for each spike unit.","name":"waveform_mean","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform standard deviation for each spike unit.","name":"waveform_sd","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[null,null],"dims":["num_waveforms","num_samples"],"dtype":"numeric","doc":"Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.","name":"waveforms","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"doc":"Index into the waveforms dataset. One value for every spike event. See 'waveforms' for more detail.","name":"waveforms_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Index into the waveforms_index dataset. One value for every unit (row in the table). See 'waveforms' for more detail.","name":"waveforms_index_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units"}]}~{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"meters"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description defining what exactly 'straight-ahead' means.","name":"reference_frame","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries"},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]}l {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Applied power for optogenetic stimulus, in watts.","name":"data","attributes":[{"doc":"Unit of measurement for data, which is fixed to 'watts'.","name":"unit","dtype":"text","value":"watts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","name":"site","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries"},{"datasets":[{"dtype":"text","doc":"Description of stimulation site.","name":"description"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"text","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"}],"links":[{"doc":"Device that generated the stimulus.","name":"device","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]} h a*cx a*c a*cSNOD(HP8Xȝ a*c a*c a*cGCOL`l9{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","doc":"Recorded voltage data.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float32","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","name":"channel_conversion","quantity":"?","attributes":[{"doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","name":"axis","dtype":"int32","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"doc":"Filtering applied to all channels of the data. For example, if this ElectricalSeries represents high-pass-filtered data (also known as AP Band), then this value could be \"High-pass 4-pole Bessel filter at 500 Hz\". If this ElectricalSeries represents low-pass-filtered LFP data and the type of filter is unknown, then this value could be \"Low-pass filter at 300 Hz\". If a non-standard filter type is used, provide as much detail about the filter properties as possible.","name":"filtering","required":false,"dtype":"text"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","doc":"Spike waveforms.","name":"data","attributes":[{"doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","name":"timestamps","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries"},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of features (eg, ''PC1'') for each of the extracted features.","name":"description"},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","doc":"Multi-dimensional array of features extracted from each event.","name":"features"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of events that features correspond to (can be a link).","name":"times"},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values.","name":"detection_method"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data.","name":"source_idx"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Timestamps of events, in seconds.","name":"times","attributes":[{"doc":"Unit of measurement for event times, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"links":[{"doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","name":"source_electricalseries","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"datasets":[{"dtype":[{"doc":"x coordinate","name":"x","dtype":"float32"},{"doc":"y coordinate","name":"y","dtype":"float32"},{"doc":"z coordinate","name":"z","dtype":"float32"}],"doc":"stereotaxic or common framework coordinates","name":"position","quantity":"?"}],"links":[{"doc":"Link to the device that was used to record from this electrode group.","name":"device","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"doc":"Description of this electrode group.","name":"description","dtype":"text"},{"doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, etc. Use standard atlas names for anatomical regions when possible.","name":"location","dtype":"text"}]},{"datasets":[{"dtype":"text","doc":"Filtering applied to data before generating mean/sd","name":"waveform_filtering"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)","name":"waveform_mean"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"Stdev of waveforms for each cluster, using the same indices as in mean","name":"waveform_sd"}],"links":[{"doc":"Link to Clustering interface that was the source of the clustered data","name":"clustering_interface","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)","name":"description"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Cluster number of each event","name":"num"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric).","name":"peak_over_rms"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module.","name":"times"}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}@{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Recorded voltage or current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","name":"gain","quantity":"?"}],"links":[{"doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","name":"electrode","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"doc":"Protocol/stimulus name for this patch-clamp dataset.","name":"stimulus_description","dtype":"text"},{"doc":"Sweep number, allows to group different PatchClampSeries together.","name":"sweep_number","required":false,"dtype":"uint32"}]},{"datasets":[{"doc":"Recorded voltage.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Bias current, in amps.","name":"bias_current","quantity":"?"},{"dtype":"float32","doc":"Bridge balance, in ohms.","name":"bridge_balance","quantity":"?"},{"dtype":"float32","doc":"Capacitance compensation, in farads.","name":"capacitance_compensation","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries"},{"datasets":[{"dtype":"float32","doc":"Bias current, in amps, fixed to 0.0.","name":"bias_current"},{"dtype":"float32","doc":"Bridge balance, in ohms, fixed to 0.0.","name":"bridge_balance"},{"dtype":"float32","doc":"Capacitance compensation, in farads, fixed to 0.0.","name":"capacitance_compensation"}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"doc":"An IZeroClampSeries has no stimulus, so this attribute is automatically set to \"N/A\"","name":"stimulus_description","dtype":"text","value":"N/A"}]},{"datasets":[{"doc":"Stimulus current applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries"},{"datasets":[{"doc":"Recorded current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Fast capacitance, in farads.","name":"capacitance_fast","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Slow capacitance, in farads.","name":"capacitance_slow","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Resistance compensation bandwidth, in hertz.","name":"resistance_comp_bandwidth","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","name":"unit","dtype":"text","value":"hertz"}]},{"dtype":"float32","doc":"Resistance compensation correction, in percent.","name":"resistance_comp_correction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Resistance compensation prediction, in percent.","name":"resistance_comp_prediction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Whole cell capacitance compensation, in farads.","name":"whole_cell_capacitance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Whole cell series resistance compensation, in ohms.","name":"whole_cell_series_resistance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","name":"unit","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries"},{"datasets":[{"doc":"Stimulus voltage applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries"},{"datasets":[{"dtype":"text","doc":"Description of electrode (e.g., whole-cell, sharp, etc.).","name":"description"},{"dtype":"text","doc":"Electrode specific filtering.","name":"filtering","quantity":"?"},{"dtype":"text","doc":"Initial access resistance.","name":"initial_access_resistance","quantity":"?"},{"dtype":"text","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","quantity":"?"},{"dtype":"text","doc":"Electrode resistance, in ohms.","name":"resistance","quantity":"?"},{"dtype":"text","doc":"Information about seal used for recording.","name":"seal","quantity":"?"},{"dtype":"text","doc":"Information about slice used for recording.","name":"slice","quantity":"?"}],"links":[{"doc":"Device that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint32","doc":"Sweep number of the PatchClampSeries in that row.","name":"sweep_number","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"doc":"The PatchClampSeries with the sweep number in that row.","name":"series","neurodata_type_inc":"VectorData"},{"doc":"Index for series.","name":"series_index","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable"}]}I2{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"}],"links":[{"doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"doc":"Photomultiplier gain.","name":"pmt_gain","required":false,"dtype":"float32"},{"doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","name":"scan_line_rate","required":false,"dtype":"float32"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","doc":"Signals from ROIs.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","name":"rois","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. The first dimension represents time. The second dimension, if present, represents ROIs.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries"},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"PlaneSegmentation"}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"doc":"Image stacks that the segmentation masks apply to.","name":"reference_images"}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","name":"image_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into pixel_mask.","name":"pixel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float32"}],"doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"pixel_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into voxel_mask.","name":"voxel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint32"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float32"}],"doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"voxel_mask","quantity":"?","neurodata_type_inc":"VectorData"}],"links":[{"doc":"Link to ImagingPlane object from which this data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation"},{"groups":[{"doc":"An optical channel used to record from an imaging plane.","quantity":"+","neurodata_type_inc":"OpticalChannel"}],"datasets":[{"dtype":"text","doc":"Description of the imaging plane.","name":"description","quantity":"?"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"float32","doc":"Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead.","name":"imaging_rate","quantity":"?"},{"dtype":"text","doc":"Calcium indicator.","name":"indicator"},{"dtype":"text","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x, y, z"],["height","width","depth","x, y, z"]],"dtype":"float32","doc":"DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing.","name":"manifold","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Base unit of measurement for working with the data. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma).","name":"origin_coords","quantity":"?","attributes":[{"doc":"Measurement units for origin_coords. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid.","name":"grid_spacing","quantity":"?","attributes":[{"doc":"Measurement units for grid_spacing. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","doc":"Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = \"Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral).\"","name":"reference_frame","quantity":"?"}],"links":[{"doc":"Link to the Device object that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An imaging plane and its metadata.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"datasets":[{"dtype":"text","doc":"Description or other notes about the channel.","name":"description"},{"dtype":"float32","doc":"Emission wavelength for channel, in nm.","name":"emission_lambda"}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"},{"groups":[{"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"},{"groups":[{"doc":"Image stack with frames shifted to the common coordinates.","name":"corrected","neurodata_type_inc":"ImageSeries"},{"doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","name":"xy_translation","neurodata_type_inc":"TimeSeries"}],"links":[{"doc":"Link to ImageSeries object that is being registered.","name":"original","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}]}x{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the first measured axis.","name":"axis_1_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_1_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the second measured axis.","name":"axis_2_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_2_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[2],"dims":["axis_1, axis_2"],"dtype":"text","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta'].","name":"axis_descriptions"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","name":"focal_depth_image","quantity":"?","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Focal depth offset, in meters.","name":"focal_depth","dtype":"float32"},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","name":"sign_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","name":"vasculature_image","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. This group does not store the raw responses imaged during retinotopic mapping or the stimuli presented, but rather the resulting phase and power maps after applying a Fourier transform on the averaged responses. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.device"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.3.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}. a*c././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/1.5.1_timeseries_no_unit.nwb0000644000175100001730000051270014467767506023054 0ustar00runnerdockerHDF  ` :TREEHAHEAP`? 0 .specloc0;HhTREE HEAPXtest_timeseries@SNOD HhP`;H788:TREE@ HEAPX datastarting_time8SNOD(Pp  @ a*c @ conversion ?@4 4?` SNOD0     qpRNZxwwhw.P6-P?PAP~Pl9P@Pl PI2PxPP @ resolution ?@4 4 ?@4 4 a*c 8rate ?@4 4? @unitPp H comments  H description H namespace Hneurodata_type  H object_id$TREEHEAPX8P-HEAPXP/XHEAPX(xpresentationtemplates01HEAPXPGCOLseconds no commentsno descriptioncore TimeSeries$1dd43f45-f547-4393-b960-ae2c96cac6af 2022-09-01T03:43:29.963766+00:00ADDME ADDME 2022-09-01T03:43:29.963532+00:00 2022-09-01T03:43:29.963532+00:00 2.3.0 coreNWBFile$74eeb7d0-4375-4bec-8354-d703382107b9q{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"}],"groups":[{"doc":"An abstract data type for a group storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"groups":[{"doc":"Container objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Container"}],"datasets":[{"doc":"Data objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Data"}],"doc":"A simple Container for holding onto multiple containers.","data_type_inc":"Container","data_type_def":"SimpleMultiContainer"}]}N{"groups":[{"datasets":[{"shape":[null],"dims":["number of non-zero values"],"dtype":"uint","doc":"The column indices.","name":"indices"},{"shape":[null],"dims":["number of rows in the matrix + 1"],"dtype":"uint","doc":"The row index pointer.","name":"indptr"},{"shape":[null],"dims":["number of non-zero values"],"doc":"The non-zero values in the matrix.","name":"data"}],"doc":"A compressed sparse row matrix. Data are stored in the standard CSR format, where column indices for row i are stored in indices[indptr[i]:indptr[i+1]] and their corresponding values are stored in data[indptr[i]:indptr[i+1]].","data_type_inc":"Container","data_type_def":"CSRMatrix","attributes":[{"doc":"The shape (number of rows, number of columns) of this sparse matrix.","name":"shape","dtype":"uint","shape":[2],"dims":["number of rows, number of columns"]}]}]}Z{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"base"},{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.5.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"datasets":[{"dtype":"uint8","doc":"Data that come from a fixed set of values. A data value of i corresponds to the i-th value in the VectorData referenced by the 'elements' attribute.","data_type_inc":"VectorData","data_type_def":"EnumData","attributes":[{"doc":"Reference to the VectorData object that contains the enumerable elements","name":"elements","dtype":{"target_type":"VectorData","reftype":"object"}}]}]}TREETREE3TREESNOD105X5x7X5x7TREEHEAPX7P88:TREEHEAPXX:P H nwb_version XC`DF a*cx a*c a*c a*cacquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODhp<(-x=>0;`DF80/XHB a*c H namespace Hneurodata_type H object_id$PTREEIHEAPX8Fhdmf-commonhdmf-experimentalcore  G@ITREEMHEAPX`I1.5.0HSNOD0؊F G@IPmxmo(KHMTREEPHEAPX0hMbasetablesparsenamespace(SNODK(KHM a*cSNODO @l0k`Q a*cGCOL{"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["dim0"],["dim0","dim1"],["dim0","dim1","dim2"],["dim0","dim1","dim2","dim3"]],"doc":"An n-dimensional dataset representing a column of a DynamicTable. If used without an accompanying VectorIndex, first dimension is along the rows of the DynamicTable and each step along the first dimension is a cell of the larger table. VectorData can also be used to represent a ragged array if paired with a VectorIndex. This allows for storing arrays of varying length in a single cell of the DynamicTable by indexing into this VectorData. The first vector is at VectorData[0:VectorIndex[0]]. The second vector is at VectorData[VectorIndex[0]:VectorIndex[1]], and so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"doc":"Description of what these vectors represent.","name":"description","dtype":"text"}]},{"shape":[null],"dims":["num_rows"],"dtype":"uint8","doc":"Used with VectorData to encode a ragged array. An array of indices into the first dimension of the target VectorData, and forming a map between the rows of a DynamicTable and the indices of the VectorData. The name of the VectorIndex is expected to be the name of the target VectorData object followed by \"_index\".","data_type_inc":"VectorData","data_type_def":"VectorIndex","attributes":[{"doc":"Reference to the target dataset that this index applies to.","name":"target","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"DynamicTableRegion provides a link from one table to an index or region of another. The `table` attribute is a link to another `DynamicTable`, indicating which table is referenced, and the data is int(s) indicating the row(s) (0-indexed) of the target array. `DynamicTableRegion`s can be used to associate rows with repeated meta-data without data duplication. They can also be used to create hierarchical relationships between multiple `DynamicTable`s. `DynamicTableRegion` objects may be paired with a `VectorIndex` object to create ragged references, so a single cell of a `DynamicTable` can reference many rows of another `DynamicTable`.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"doc":"Reference to the DynamicTable object that this region applies to.","name":"table","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"doc":"Description of what this table region points to.","name":"description","dtype":"text"}]}],"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"Array of unique identifiers for the rows of this dynamic table.","name":"id","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns, including index columns, of this dynamic table.","quantity":"*","data_type_inc":"VectorData"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). These datasets represent different columns in the table. Apart from a column that contains unique identifiers for each row, there are no other required datasets. Users are free to add any number of custom VectorData objects (columns) here. DynamicTable also supports ragged array columns, where each element can be of a different size. To add a ragged array column, use a VectorIndex type to index the corresponding VectorData type. See documentation for VectorData and VectorIndex for more details. Unlike a compound data type, which is analogous to storing an array-of-structs, a DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"doc":"The names of the columns in this table. This should be used to specify an order to the columns.","name":"colnames","dtype":"text","shape":[null],"dims":["num_columns"]},{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text"}]},{"groups":[{"doc":"A DynamicTable representing a particular category for columns in the AlignedDynamicTable parent container. The table MUST be aligned with (i.e., have the same number of rows) as all other DynamicTables stored in the AlignedDynamicTable parent container. The name of the category is given by the name of the DynamicTable and its description by the description attribute of the DynamicTable.","quantity":"*","data_type_inc":"DynamicTable"}],"doc":"DynamicTable container that supports storing a collection of sub-tables. Each sub-table is a DynamicTable itself that is aligned with the main table by row index. I.e., all DynamicTables stored in this group MUST have the same number of rows. This type effectively defines a 2-level table in which the main data is stored in the main table implemented by this type and additional columns of the table are grouped into categories, with each category being represented by a separate DynamicTable stored within the group.","data_type_inc":"DynamicTable","data_type_def":"AlignedDynamicTable","attributes":[{"doc":"The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.","name":"categories","dtype":"text","shape":[null],"dims":["num_categories"]}]}]}a*ca*cxmoTREErHEAPXo0.1.0H8pXrTREE(uHEAPX8xrexperimentalresourcesnamespace SNODp8pXr(b*cSNODt(pv8b*cGCOLx{"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The user term that maps to one or more resources in the 'resources' table.","name":"key","dtype":"text"}],"doc":"A table for storing user terms that are used to refer to external resources.","name":"keys","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the key in the 'keys' table.","name":"keys_idx","dtype":"uint"},{"doc":"The index into the 'resources' table","name":"resources_idx","dtype":"uint"},{"doc":"The unique identifier entity.","name":"entity_id","dtype":"text"},{"doc":"The URI for the entity this reference applies to. This can be an empty string.","name":"entity_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"entities","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The name of the resource.","name":"resource","dtype":"text"},{"doc":"The URI for the resource. This can be an empty string.","name":"resource_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"resources","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The UUID for the object.","name":"object_id","dtype":"text"},{"doc":"The field of the object. This can be an empty string if the object is a dataset and the field is the dataset values.","name":"field","dtype":"text"}],"doc":"A table for identifying which objects in a file contain references to external resources.","name":"objects","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the 'objects' table for the object that holds the key.","name":"objects_idx","dtype":"uint"},{"doc":"The index to the 'keys' table for the key.","name":"keys_idx","dtype":"uint"}],"doc":"A table for identifying which objects use which keys.","name":"object_keys","data_type_inc":"Data"}],"doc":"A set of four tables for tracking external resource references in a file. NOTE: this data type is in beta testing and is subject to change in a later version.","data_type_inc":"Container","data_type_def":"ExternalResources"}]}{"namespaces":[{"doc":"Experimental data structures provided by HDMF. These are not guaranteed to be available in the future","schema":[{"namespace":"hdmf-common"},{"source":"experimental"},{"source":"resources"}],"name":"hdmf-experimental","full_name":"HDMF Experimental","version":"0.1.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"groups":[{"doc":"Metadata about a data acquisition device, e.g., recording system, electrode, microscope.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"doc":"Description of the device (e.g., model, firmware version, processing software version, etc.) as free-form text.","name":"description","required":false,"dtype":"text"},{"doc":"The name of the manufacturer of the device.","name":"manufacturer","required":false,"dtype":"text"}]}]}Hb*c؊TREEHEAPX2.3.0HxTREEPxHEAP`SNODPxXb*cGCOL{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["x","y"],["x","y","r, g, b"],["x","y","r, g, b, a"]],"dtype":"numeric","doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"doc":"Pixel resolution of the image, in pixels per centimeter.","name":"resolution","required":false,"dtype":"float32"},{"doc":"Description of the image.","name":"description","required":false,"dtype":"text"}]}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","name":"sync","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float64","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","name":"starting_time","quantity":"?","attributes":[{"doc":"Sampling rate, in Hz.","name":"rate","dtype":"float32"},{"doc":"Unit of measurement for time, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","name":"timestamps","quantity":"?","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","name":"control","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","name":"control_description","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"doc":"Description of the time series.","name":"description","required":false,"dtype":"text","default_value":"no description"},{"doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","name":"comments","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"doc":"Description of this collection of processed data.","name":"description","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"}],"doc":"A collection of images.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"doc":"Description of this collection of images.","name":"description","dtype":"text"}]}]}SNODXhPx`hb*cxb*cb*cb*cb*cnwb.basenwb.devicenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOL.{"groups":[{"datasets":[{"dtype":"float32","doc":"Start time of epoch, in seconds.","name":"start_time","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Stop time of epoch, in seconds.","name":"stop_time","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"User-defined tags that identify or categorize events.","name":"tags","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for tags.","name":"tags_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch.","name":"count","dtype":"int32"},{"doc":"the TimeSeries that this index applies to.","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"doc":"An index into a TimeSeries object.","name":"timeseries","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for timeseries.","name":"timeseries_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals"}]}6-{"datasets":[{"shape":[null,null],"dims":["x","y"],"dtype":"numeric","doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage"},{"shape":[null,null,3],"dims":["x","y","r, g, b"],"dtype":"numeric","doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage"},{"shape":[null,null,4],"dims":["x","y","r, g, b, a"],"dtype":"numeric","doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage"}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","x","y"],["frame","x","y","z"]],"dtype":"numeric","doc":"Binary data representing images across frames.","name":"data","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","doc":"Number of pixels on x, y, (and z) axes.","name":"dimension","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","name":"external_file","quantity":"?","attributes":[{"doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","name":"starting_frame","dtype":"int32","shape":[null],"dims":["num_files"]}]},{"dtype":"text","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","name":"format","quantity":"?","default_value":"raw"}],"links":[{"doc":"Link to the Device object that was used to capture these images.","name":"device","target_type":"Device","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][x][y] or [frame][x][y][z].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries"},{"links":[{"doc":"Link to ImageSeries object that this image mask is applied to.","name":"masked_imageseries","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries"},{"datasets":[{"dtype":"float32","doc":"Distance from camera/monitor to target/eye.","name":"distance","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"},{"shape":[[null,null,null],[null,null,null,3]],"dims":[["frame","x","y"],["frame","x","y","r, g, b"]],"dtype":"numeric","doc":"Images presented to subject, either grayscale or RGB","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","name":"orientation","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int32","doc":"Index of the frame in the referenced ImageSeries.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to ImageSeries object containing images that are indexed.","name":"indexed_timeseries","target_type":"ImageSeries"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries"}]}?{"datasets":[{"doc":"Any one-off datasets","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"doc":"Any notes the user has about the dataset being stored","name":"notes","dtype":"text"}]}],"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.","name":"acquisition"},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.","name":"analysis"},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"ScratchData"}],"doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","name":"scratch","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.","name":"processing"},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Stimuli presented during the experiment.","name":"presentation"},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.","name":"templates"}],"doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file.","name":"stimulus"},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"LabMetaData"},{"groups":[{"doc":"Data acquisition devices.","quantity":"*","neurodata_type_inc":"Device"}],"doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","name":"devices","quantity":"?"},{"doc":"Information about the animal or person from which the data was measured.","name":"subject","quantity":"?","neurodata_type_inc":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float32","doc":"x coordinate of the channel location in the brain (+x is posterior).","name":"x","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate of the channel location in the brain (+y is inferior).","name":"y","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate of the channel location in the brain (+z is right).","name":"z","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Impedance of the channel, in ohms.","name":"imp","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Description of hardware filtering, including the filter name and frequency cutoffs.","name":"filtering","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Reference to the ElectrodeGroup this electrode is a part of.","name":"group","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Name of the ElectrodeGroup this electrode is a part of.","name":"group_name","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"x coordinate in electrode group","name":"rel_x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate in electrode group","name":"rel_y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate in electrode group","name":"rel_z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of the reference used for this electrode.","name":"reference","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"A table of all electrodes (i.e. channels) used for recording.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTable"}],"doc":"Metadata related to extracellular electrophysiology.","name":"extracellular_ephys","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"doc":"The table which groups different PatchClampSeries together.","name":"sweep_table","quantity":"?","neurodata_type_inc":"SweepTable"}],"datasets":[{"dtype":"text","doc":"Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","name":"filtering","quantity":"?"}],"doc":"Metadata related to intracellular electrophysiology.","name":"intracellular_ephys","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"doc":"Metadata describing optogenetic stimuluation.","name":"optogenetics","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"doc":"Metadata related to optophysiology.","name":"optophysiology","quantity":"?"}],"datasets":[{"dtype":"text","doc":"Notes about data collection and analysis.","name":"data_collection","quantity":"?"},{"dtype":"text","doc":"General description of the experiment.","name":"experiment_description","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","name":"experimenter","quantity":"?"},{"dtype":"text","doc":"Institution(s) where experiment was performed.","name":"institution","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","doc":"Terms to search over.","name":"keywords","quantity":"?"},{"dtype":"text","doc":"Laboratory where experiment was performed.","name":"lab","quantity":"?"},{"dtype":"text","doc":"Notes about the experiment.","name":"notes","quantity":"?"},{"dtype":"text","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","name":"pharmacology","quantity":"?"},{"dtype":"text","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","name":"protocol","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","doc":"Publication information. PMID, DOI, URL, etc.","name":"related_publications","quantity":"?"},{"dtype":"text","doc":"Lab-specific ID for the session.","name":"session_id","quantity":"?"},{"dtype":"text","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","name":"slices","quantity":"?"},{"dtype":"text","doc":"Script file or link to public source code used to create this NWB file.","name":"source_script","quantity":"?","attributes":[{"doc":"Name of script file.","name":"file_name","dtype":"text"}]},{"dtype":"text","doc":"Notes about stimuli, such as how and where they were presented.","name":"stimulus","quantity":"?"},{"dtype":"text","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","name":"surgery","quantity":"?"},{"dtype":"text","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","name":"virus","quantity":"?"}],"doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them.","name":"general"},{"groups":[{"doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","name":"epochs","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Repeated experimental events that have a logical grouping.","name":"trials","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Time intervals that should be removed from analysis.","name":"invalid_times","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","name":"intervals","quantity":"?"},{"doc":"Data about sorted spike units.","name":"units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array.","name":"file_create_date"},{"dtype":"text","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files.","name":"identifier"},{"dtype":"text","doc":"A description of the experimental session and data in the file.","name":"session_description"},{"dtype":"isodatetime","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds.","name":"session_start_time"},{"dtype":"isodatetime","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).","name":"timestamps_reference_time"}],"doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","name":"root","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","name":"nwb_version","dtype":"text","value":"2.3.0"}]},{"doc":"Lab-specific meta-data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"datasets":[{"dtype":"text","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","name":"age","quantity":"?"},{"dtype":"isodatetime","doc":"Date of birth of subject. Can be supplied instead of 'age'.","name":"date_of_birth","quantity":"?"},{"dtype":"text","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","name":"description","quantity":"?"},{"dtype":"text","doc":"Genetic strain. If absent, assume Wild Type (WT).","name":"genotype","quantity":"?"},{"dtype":"text","doc":"Gender of subject.","name":"sex","quantity":"?"},{"dtype":"text","doc":"Species of subject.","name":"species","quantity":"?"},{"dtype":"text","doc":"Strain of subject.","name":"strain","quantity":"?"},{"dtype":"text","doc":"ID of animal/person used/participating in experiment (lab convention).","name":"subject_id","quantity":"?"},{"dtype":"text","doc":"Weight at time of experiment, at time of surgery and at other important times.","name":"weight","quantity":"?"}],"doc":"Information about the animal or person from which the data was measured.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"}]}A{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"Values of each feature at each time.","name":"data","attributes":[{"doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","name":"unit","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Units of each feature.","name":"feature_units","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of the features represented in TimeSeries::data.","name":"features"}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","doc":"Annotations made during an experiment.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","doc":"Use values >0 if interval started, <0 if interval ended.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries"},{"groups":[{"datasets":[{"dtype":"text","doc":"Name of the band, e.g. theta.","name":"band_name","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float32","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","name":"band_limits","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The mean Gaussian filters, in Hz.","name":"band_mean","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The standard deviation of Gaussian filters, in Hz.","name":"band_stdev","neurodata_type_inc":"VectorData"}],"doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","name":"bands","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","doc":"Data decomposed into frequency bands.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"no unit"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"The metric used, e.g. phase, amplitude, power.","name":"metric"},{"doc":"DynamicTableRegion pointer to the channels that this decomposition series was generated from.","name":"source_channels","quantity":"?","neurodata_type_inc":"DynamicTableRegion"}],"links":[{"doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","name":"source_timeseries","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries"},{"datasets":[{"doc":"Index into the spike_times dataset.","name":"spike_times_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"float64","doc":"Spike times for each unit.","name":"spike_times","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"The smallest possible difference between two spike times. Usually 1 divided by the acquisition sampling rate from which spike times were extracted, but could be larger if the acquisition time series was downsampled or smaller if the acquisition time series was smoothed/interpolated and it is possible for the spike time to be between samples.","name":"resolution","required":false,"dtype":"float64"}]},{"doc":"Index into the obs_intervals dataset.","name":"obs_intervals_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"float64","doc":"Observation intervals for each unit.","name":"obs_intervals","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into electrodes.","name":"electrodes_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Electrode group that each spike unit came from.","name":"electrode_group","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform mean for each spike unit.","name":"waveform_mean","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform standard deviation for each spike unit.","name":"waveform_sd","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[null,null],"dims":["num_waveforms","num_samples"],"dtype":"numeric","doc":"Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.","name":"waveforms","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"doc":"Index into the waveforms dataset. One value for every spike event. See 'waveforms' for more detail.","name":"waveforms_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Index into the waveforms_index dataset. One value for every unit (row in the table). See 'waveforms' for more detail.","name":"waveforms_index_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units"}]}~{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"meters"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description defining what exactly 'straight-ahead' means.","name":"reference_frame","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries"},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]}l {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Applied power for optogenetic stimulus, in watts.","name":"data","attributes":[{"doc":"Unit of measurement for data, which is fixed to 'watts'.","name":"unit","dtype":"text","value":"watts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","name":"site","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries"},{"datasets":[{"dtype":"text","doc":"Description of stimulation site.","name":"description"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"text","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"}],"links":[{"doc":"Device that generated the stimulus.","name":"device","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]} b*cb*cb*cSNOD(Hȯp8XذȜ؝b*cb*cb*cGCOL`l9{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","doc":"Recorded voltage data.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float32","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","name":"channel_conversion","quantity":"?","attributes":[{"doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","name":"axis","dtype":"int32","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"doc":"Filtering applied to all channels of the data. For example, if this ElectricalSeries represents high-pass-filtered data (also known as AP Band), then this value could be \"High-pass 4-pole Bessel filter at 500 Hz\". If this ElectricalSeries represents low-pass-filtered LFP data and the type of filter is unknown, then this value could be \"Low-pass filter at 300 Hz\". If a non-standard filter type is used, provide as much detail about the filter properties as possible.","name":"filtering","required":false,"dtype":"text"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","doc":"Spike waveforms.","name":"data","attributes":[{"doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","name":"timestamps","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries"},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of features (eg, ''PC1'') for each of the extracted features.","name":"description"},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","doc":"Multi-dimensional array of features extracted from each event.","name":"features"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of events that features correspond to (can be a link).","name":"times"},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values.","name":"detection_method"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data.","name":"source_idx"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Timestamps of events, in seconds.","name":"times","attributes":[{"doc":"Unit of measurement for event times, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"links":[{"doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","name":"source_electricalseries","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"datasets":[{"dtype":[{"doc":"x coordinate","name":"x","dtype":"float32"},{"doc":"y coordinate","name":"y","dtype":"float32"},{"doc":"z coordinate","name":"z","dtype":"float32"}],"doc":"stereotaxic or common framework coordinates","name":"position","quantity":"?"}],"links":[{"doc":"Link to the device that was used to record from this electrode group.","name":"device","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"doc":"Description of this electrode group.","name":"description","dtype":"text"},{"doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, etc. Use standard atlas names for anatomical regions when possible.","name":"location","dtype":"text"}]},{"datasets":[{"dtype":"text","doc":"Filtering applied to data before generating mean/sd","name":"waveform_filtering"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)","name":"waveform_mean"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"Stdev of waveforms for each cluster, using the same indices as in mean","name":"waveform_sd"}],"links":[{"doc":"Link to Clustering interface that was the source of the clustered data","name":"clustering_interface","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)","name":"description"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Cluster number of each event","name":"num"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric).","name":"peak_over_rms"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module.","name":"times"}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}@{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Recorded voltage or current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","name":"gain","quantity":"?"}],"links":[{"doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","name":"electrode","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"doc":"Protocol/stimulus name for this patch-clamp dataset.","name":"stimulus_description","dtype":"text"},{"doc":"Sweep number, allows to group different PatchClampSeries together.","name":"sweep_number","required":false,"dtype":"uint32"}]},{"datasets":[{"doc":"Recorded voltage.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Bias current, in amps.","name":"bias_current","quantity":"?"},{"dtype":"float32","doc":"Bridge balance, in ohms.","name":"bridge_balance","quantity":"?"},{"dtype":"float32","doc":"Capacitance compensation, in farads.","name":"capacitance_compensation","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries"},{"datasets":[{"dtype":"float32","doc":"Bias current, in amps, fixed to 0.0.","name":"bias_current"},{"dtype":"float32","doc":"Bridge balance, in ohms, fixed to 0.0.","name":"bridge_balance"},{"dtype":"float32","doc":"Capacitance compensation, in farads, fixed to 0.0.","name":"capacitance_compensation"}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"doc":"An IZeroClampSeries has no stimulus, so this attribute is automatically set to \"N/A\"","name":"stimulus_description","dtype":"text","value":"N/A"}]},{"datasets":[{"doc":"Stimulus current applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries"},{"datasets":[{"doc":"Recorded current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Fast capacitance, in farads.","name":"capacitance_fast","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Slow capacitance, in farads.","name":"capacitance_slow","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Resistance compensation bandwidth, in hertz.","name":"resistance_comp_bandwidth","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","name":"unit","dtype":"text","value":"hertz"}]},{"dtype":"float32","doc":"Resistance compensation correction, in percent.","name":"resistance_comp_correction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Resistance compensation prediction, in percent.","name":"resistance_comp_prediction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Whole cell capacitance compensation, in farads.","name":"whole_cell_capacitance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Whole cell series resistance compensation, in ohms.","name":"whole_cell_series_resistance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","name":"unit","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries"},{"datasets":[{"doc":"Stimulus voltage applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries"},{"datasets":[{"dtype":"text","doc":"Description of electrode (e.g., whole-cell, sharp, etc.).","name":"description"},{"dtype":"text","doc":"Electrode specific filtering.","name":"filtering","quantity":"?"},{"dtype":"text","doc":"Initial access resistance.","name":"initial_access_resistance","quantity":"?"},{"dtype":"text","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","quantity":"?"},{"dtype":"text","doc":"Electrode resistance, in ohms.","name":"resistance","quantity":"?"},{"dtype":"text","doc":"Information about seal used for recording.","name":"seal","quantity":"?"},{"dtype":"text","doc":"Information about slice used for recording.","name":"slice","quantity":"?"}],"links":[{"doc":"Device that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint32","doc":"Sweep number of the PatchClampSeries in that row.","name":"sweep_number","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"doc":"The PatchClampSeries with the sweep number in that row.","name":"series","neurodata_type_inc":"VectorData"},{"doc":"Index for series.","name":"series_index","neurodata_type_inc":"VectorIndex"}],"doc":"The table which groups different PatchClampSeries together.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable"}]}I2{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"}],"links":[{"doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"doc":"Photomultiplier gain.","name":"pmt_gain","required":false,"dtype":"float32"},{"doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","name":"scan_line_rate","required":false,"dtype":"float32"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","doc":"Signals from ROIs.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","name":"rois","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. The first dimension represents time. The second dimension, if present, represents ROIs.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries"},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"PlaneSegmentation"}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"doc":"Image stacks that the segmentation masks apply to.","name":"reference_images"}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","name":"image_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into pixel_mask.","name":"pixel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float32"}],"doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"pixel_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into voxel_mask.","name":"voxel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint32"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float32"}],"doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"voxel_mask","quantity":"?","neurodata_type_inc":"VectorData"}],"links":[{"doc":"Link to ImagingPlane object from which this data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation"},{"groups":[{"doc":"An optical channel used to record from an imaging plane.","quantity":"+","neurodata_type_inc":"OpticalChannel"}],"datasets":[{"dtype":"text","doc":"Description of the imaging plane.","name":"description","quantity":"?"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"float32","doc":"Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead.","name":"imaging_rate","quantity":"?"},{"dtype":"text","doc":"Calcium indicator.","name":"indicator"},{"dtype":"text","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x, y, z"],["height","width","depth","x, y, z"]],"dtype":"float32","doc":"DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing.","name":"manifold","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Base unit of measurement for working with the data. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma).","name":"origin_coords","quantity":"?","attributes":[{"doc":"Measurement units for origin_coords. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid.","name":"grid_spacing","quantity":"?","attributes":[{"doc":"Measurement units for grid_spacing. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","doc":"Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = \"Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral).\"","name":"reference_frame","quantity":"?"}],"links":[{"doc":"Link to the Device object that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An imaging plane and its metadata.","quantity":"*","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"datasets":[{"dtype":"text","doc":"Description or other notes about the channel.","name":"description"},{"dtype":"float32","doc":"Emission wavelength for channel, in nm.","name":"emission_lambda"}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"},{"groups":[{"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"},{"groups":[{"doc":"Image stack with frames shifted to the common coordinates.","name":"corrected","neurodata_type_inc":"ImageSeries"},{"doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","name":"xy_translation","neurodata_type_inc":"TimeSeries"}],"links":[{"doc":"Link to ImageSeries object that is being registered.","name":"original","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}]}x{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the first measured axis.","name":"axis_1_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_1_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the second measured axis.","name":"axis_2_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_2_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[2],"dims":["axis_1, axis_2"],"dtype":"text","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta'].","name":"axis_descriptions"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","name":"focal_depth_image","quantity":"?","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Focal depth offset, in meters.","name":"focal_depth","dtype":"float32"},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","name":"sign_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","name":"vasculature_image","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. This group does not store the raw responses imaged during retinotopic mapping or the stimuli presented, but rather the resulting phase and power maps after applying a Fourier transform on the averaged responses. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.device"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.3.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}.b*c././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/2.1.0_imageseries_no_data.nwb0000644000175100001730000054400014467767506023124 0ustar00runnerdockerHDF  ` =hTREEH`CHEAP`B 0 .speclocx=HhTREE HEAPX test_imageseries8SNOD Hh0#X#x%P=HP:x:<!TREE@ (HEAPX8 dataexternal_fileformattimestamps SNOD(Pp  8 @ conversion ?@4 4? SNOD0 X h(x 8offset ?@4 4 @ resolution ?@4 4 @unitXGCOLunknown external_fileexternalseconds no commentsno descriptioncore ImageSeries $6f6806b1-fba3-4f35-9d99-3c6bac5a2249 2022-10-18T18:51:49.294576+00:00 ADDME ADDME 2022-10-18T18:51:49.294348+00:00 2022-10-18T18:51:49.294348+00:002.5.0coreNWBFile$83a6fa3d-381c-4201-b4f6-f962ca189f38q{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"}],"groups":[{"doc":"An abstract data type for a group storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"groups":[{"doc":"Container objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Container"}],"datasets":[{"doc":"Data objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Data"}],"doc":"A simple Container for holding onto multiple containers.","data_type_inc":"Container","data_type_def":"SimpleMultiContainer"}]}N{"groups":[{"datasets":[{"shape":[null],"dims":["number of non-zero values"],"dtype":"uint","doc":"The column indices.","name":"indices"},{"shape":[null],"dims":["number of rows in the matrix + 1"],"dtype":"uint","doc":"The row index pointer.","name":"indptr"},{"shape":[null],"dims":["number of non-zero values"],"doc":"The non-zero values in the matrix.","name":"data"}],"doc":"A compressed sparse row matrix. Data are stored in the standard CSR format, where column indices for row i are stored in indices[indptr[i]:indptr[i+1]] and their corresponding values are stored in data[indptr[i]:indptr[i+1]].","data_type_inc":"Container","data_type_def":"CSRMatrix","attributes":[{"doc":"The shape (number of rows, number of columns) of this sparse matrix.","name":"shape","dtype":"uint","shape":[2],"dims":["number of rows, number of columns"]}]}]}Z{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"base"},{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.5.1","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"datasets":[{"dtype":"uint8","doc":"Data that come from a fixed set of values. A data value of i corresponds to the i-th value in the VectorData referenced by the 'elements' attribute.","data_type_inc":"VectorData","data_type_def":"EnumData","attributes":[{"doc":"Reference to the VectorData object that contains the enumerable elements","name":"elements","dtype":{"target_type":"VectorData","reftype":"object"}}]}]}{"groups":[{"datasets":[{"dtype":"float32","doc":"Start time of epoch, in seconds.","name":"start_time","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Stop time of epoch, in seconds.","name":"stop_time","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"User-defined tags that identify or categorize events.","name":"tags","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for tags.","name":"tags_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"An index into a TimeSeries object.","name":"timeseries","quantity":"?","neurodata_type_inc":"TimeSeriesReferenceVectorData"},{"doc":"Index for timeseries.","name":"timeseries_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals"}]}X& H starting_frame@8h& ?@4 4x& 8 interval@ @unitXPp H comments X H descriptionX H namespaceX Hneurodata_type X H object_id$X X#x%TREEHEAPX%PX.x003 XX?@@ X X X X XqXTNXZXX yyY"yX>/J~Hf< f  3^x^^TREEHEAPX0PTREEH6HEAPX(03presentationtemplates035TREEHEAPX5PSNOD33577979TREEHEAPX9Px:<TREEHEAPX<PE H nwb_versionXFH&&&&acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh>(%X.x0x?@x=FH8&03D&P H namespaceX Hneurodata_typeX H object_id$XTREELHEAPX8Ihdmf-commonhdmf-experimentalcore IKTREE PHEAPXK1.5.1HSNOD08XIIKooqMOTREExRHEAPX0Obasetablesparsenamespace(SNOD`MMO&SNODhQ nmS&GCOL{"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["dim0"],["dim0","dim1"],["dim0","dim1","dim2"],["dim0","dim1","dim2","dim3"]],"doc":"An n-dimensional dataset representing a column of a DynamicTable. If used without an accompanying VectorIndex, first dimension is along the rows of the DynamicTable and each step along the first dimension is a cell of the larger table. VectorData can also be used to represent a ragged array if paired with a VectorIndex. This allows for storing arrays of varying length in a single cell of the DynamicTable by indexing into this VectorData. The first vector is at VectorData[0:VectorIndex[0]]. The second vector is at VectorData[VectorIndex[0]:VectorIndex[1]], and so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"doc":"Description of what these vectors represent.","name":"description","dtype":"text"}]},{"shape":[null],"dims":["num_rows"],"dtype":"uint8","doc":"Used with VectorData to encode a ragged array. An array of indices into the first dimension of the target VectorData, and forming a map between the rows of a DynamicTable and the indices of the VectorData. The name of the VectorIndex is expected to be the name of the target VectorData object followed by \"_index\".","data_type_inc":"VectorData","data_type_def":"VectorIndex","attributes":[{"doc":"Reference to the target dataset that this index applies to.","name":"target","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"DynamicTableRegion provides a link from one table to an index or region of another. The `table` attribute is a link to another `DynamicTable`, indicating which table is referenced, and the data is int(s) indicating the row(s) (0-indexed) of the target array. `DynamicTableRegion`s can be used to associate rows with repeated meta-data without data duplication. They can also be used to create hierarchical relationships between multiple `DynamicTable`s. `DynamicTableRegion` objects may be paired with a `VectorIndex` object to create ragged references, so a single cell of a `DynamicTable` can reference many rows of another `DynamicTable`.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"doc":"Reference to the DynamicTable object that this region applies to.","name":"table","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"doc":"Description of what this table region points to.","name":"description","dtype":"text"}]}],"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"Array of unique identifiers for the rows of this dynamic table.","name":"id","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns, including index columns, of this dynamic table.","quantity":"*","data_type_inc":"VectorData"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). These datasets represent different columns in the table. Apart from a column that contains unique identifiers for each row, there are no other required datasets. Users are free to add any number of custom VectorData objects (columns) here. DynamicTable also supports ragged array columns, where each element can be of a different size. To add a ragged array column, use a VectorIndex type to index the corresponding VectorData type. See documentation for VectorData and VectorIndex for more details. Unlike a compound data type, which is analogous to storing an array-of-structs, a DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"doc":"The names of the columns in this table. This should be used to specify an order to the columns.","name":"colnames","dtype":"text","shape":[null],"dims":["num_columns"]},{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text"}]},{"groups":[{"doc":"A DynamicTable representing a particular category for columns in the AlignedDynamicTable parent container. The table MUST be aligned with (i.e., have the same number of rows) as all other DynamicTables stored in the AlignedDynamicTable parent container. The name of the category is given by the name of the DynamicTable and its description by the description attribute of the DynamicTable.","quantity":"*","data_type_inc":"DynamicTable"}],"doc":"DynamicTable container that supports storing a collection of sub-tables. Each sub-table is a DynamicTable itself that is aligned with the main table by row index. I.e., all DynamicTables stored in this group MUST have the same number of rows. This type effectively defines a 2-level table in which the main data is stored in the main table implemented by this type and additional columns of the table are grouped into categories, with each category being represented by a separate DynamicTable stored within the group.","data_type_inc":"DynamicTable","data_type_def":"AlignedDynamicTable","attributes":[{"doc":"The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.","name":"categories","dtype":"text","shape":[null],"dims":["num_categories"]}]}]}''oqTREE0uHEAPXr0.2.0HrtTREEwHEAPX8texperimentalresourcesnamespace SNODprrt 'SNODxv(x0'GCOL {"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The user term that maps to one or more resources in the 'resources' table.","name":"key","dtype":"text"}],"doc":"A table for storing user terms that are used to refer to external resources.","name":"keys","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the key in the 'keys' table.","name":"keys_idx","dtype":"uint"},{"doc":"The index into the 'resources' table","name":"resources_idx","dtype":"uint"},{"doc":"The unique identifier entity.","name":"entity_id","dtype":"text"},{"doc":"The URI for the entity this reference applies to. This can be an empty string.","name":"entity_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"entities","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The name of the resource.","name":"resource","dtype":"text"},{"doc":"The URI for the resource. This can be an empty string.","name":"resource_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"resources","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The UUID for the object.","name":"object_id","dtype":"text"},{"doc":"The relative path from the container with the object_id to the dataset or attribute with the value(s) that is associated with an external resource. This can be an empty string if the container is a dataset which contains the value(s) that is associated with an external resource.","name":"relative_path","dtype":"text"},{"doc":"The field of the compound data type using an external resource. This is used only if the dataset or attribute is a compound data type; otherwise this should be an empty string.","name":"field","dtype":"text"}],"doc":"A table for identifying which objects in a file contain references to external resources.","name":"objects","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the 'objects' table for the object that holds the key.","name":"objects_idx","dtype":"uint"},{"doc":"The index to the 'keys' table for the key.","name":"keys_idx","dtype":"uint"}],"doc":"A table for identifying which objects use which keys.","name":"object_keys","data_type_inc":"Data"}],"doc":"A set of four tables for tracking external resource references in a file. NOTE: this data type is in beta testing and is subject to change in a later version.","data_type_inc":"Container","data_type_def":"ExternalResources"}]}{"namespaces":[{"doc":"Experimental data structures provided by HDMF. These are not guaranteed to be available in the future.","schema":[{"namespace":"hdmf-common"},{"source":"experimental"},{"source":"resources"}],"name":"hdmf-experimental","full_name":"HDMF Experimental","version":"0.2.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Matthew Avaylon"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","mavaylon@lbl.gov"]}]}{"groups":[{"doc":"Metadata about a data acquisition device, e.g., recording system, electrode, microscope.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"doc":"Description of the device (e.g., model, firmware version, processing software version, etc.) as free-form text.","name":"description","required":false,"dtype":"text"},{"doc":"The name of the manufacturer of the device.","name":"manufacturer","required":false,"dtype":"text"}]}]}@'8TREEpHEAPXX2.5.0H؍TREEȒx@HEAP`SNOD؍P'SNODhx GCOL"Y"{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch","name":"count","dtype":"int32"},{"doc":"The TimeSeries that this index applies to","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"doc":"Column storing references to a TimeSeries (rows). For each TimeSeries this VectorData column stores the start_index and count to indicate the range in time to be selected as well as an object reference to the TimeSeries.","default_name":"timeseries","neurodata_type_inc":"VectorData","neurodata_type_def":"TimeSeriesReferenceVectorData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["x","y"],["x","y","r, g, b"],["x","y","r, g, b, a"]],"dtype":"numeric","doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"doc":"Pixel resolution of the image, in pixels per centimeter.","name":"resolution","required":false,"dtype":"float32"},{"doc":"Description of the image.","name":"description","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_images"],"dtype":{"target_type":"Image","reftype":"object"},"doc":"Ordered dataset of references to Image objects.","neurodata_type_inc":"NWBData","neurodata_type_def":"ImageReferences"}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","name":"sync","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float64","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","name":"starting_time","quantity":"?","attributes":[{"doc":"Sampling rate, in Hz.","name":"rate","dtype":"float32"},{"doc":"Unit of measurement for time, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","name":"timestamps","quantity":"?","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","name":"control","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","name":"control_description","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"doc":"Description of the time series.","name":"description","required":false,"dtype":"text","default_value":"no description"},{"doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","name":"comments","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"doc":"Description of this collection of processed data.","name":"description","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"},{"doc":"Ordered dataset of references to Image objects stored in the parent group. Each Image object in the Images group should be stored once and only once, so the dataset should have the same length as the number of images.","name":"order_of_images","quantity":"?","neurodata_type_inc":"ImageReferences"}],"doc":"A collection of images with an optional way to specify the order of the images using the \"order_of_images\" dataset. An order must be specified if the images are referenced by index, e.g., from an IndexSeries.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"doc":"Description of this collection of images.","name":"description","dtype":"text"}]}]}`'p'''''GCOL>/{"datasets":[{"shape":[null,null],"dims":["x","y"],"dtype":"numeric","doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage"},{"shape":[null,null,3],"dims":["x","y","r, g, b"],"dtype":"numeric","doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage"},{"shape":[null,null,4],"dims":["x","y","r, g, b, a"],"dtype":"numeric","doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage"}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","x","y"],["frame","x","y","z"]],"dtype":"numeric","doc":"Binary data representing images across frames. If data are stored in an external file, this should be an empty 3D array.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","doc":"Number of pixels on x, y, (and z) axes.","name":"dimension","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","name":"external_file","quantity":"?","attributes":[{"doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","name":"starting_frame","dtype":"int32","shape":[null],"dims":["num_files"]}]},{"dtype":"text","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","name":"format","quantity":"?","default_value":"raw"}],"links":[{"doc":"Link to the Device object that was used to capture these images.","name":"device","target_type":"Device","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][x][y] or [frame][x][y][z].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries"},{"links":[{"doc":"Link to ImageSeries object that this image mask is applied to.","name":"masked_imageseries","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries"},{"datasets":[{"dtype":"float32","doc":"Distance from camera/monitor to target/eye.","name":"distance","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"},{"shape":[[null,null,null],[null,null,null,3]],"dims":[["frame","x","y"],["frame","x","y","r, g, b"]],"dtype":"numeric","doc":"Images presented to subject, either grayscale or RGB","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","name":"orientation","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"uint32","doc":"Index of the image (using zero-indexing) in the linked Images object.","name":"data","attributes":[{"doc":"This field is unused by IndexSeries.","name":"conversion","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries.","name":"resolution","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries.","name":"offset","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries and has the value N/A.","name":"unit","dtype":"text","value":"N/A"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to ImageSeries object containing images that are indexed. Use of this link is discouraged and will be deprecated. Link to an Images type instead.","name":"indexed_timeseries","target_type":"ImageSeries","quantity":"?"},{"doc":"Link to Images object containing an ordered set of images that are indexed. The Images object must contain a 'ordered_images' dataset specifying the order of the images in the Images type.","name":"indexed_images","target_type":"Images","quantity":"?"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the IndexSeries is to allow a static image stack to be stored in an Images object, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced Images object, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries"}]}J{"datasets":[{"doc":"Any one-off datasets","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"doc":"Any notes the user has about the dataset being stored","name":"notes","dtype":"text"}]}],"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.","name":"acquisition"},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.","name":"analysis"},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"ScratchData"}],"doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","name":"scratch","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.","name":"processing"},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Stimuli presented during the experiment.","name":"presentation"},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"},{"doc":"Images objects containing images of presented stimuli.","quantity":"*","neurodata_type_inc":"Images"}],"doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.","name":"templates"}],"doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file.","name":"stimulus"},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"LabMetaData"},{"groups":[{"doc":"Data acquisition devices.","quantity":"*","neurodata_type_inc":"Device"}],"doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","name":"devices","quantity":"?"},{"doc":"Information about the animal or person from which the data was measured.","name":"subject","quantity":"?","neurodata_type_inc":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float32","doc":"x coordinate of the channel location in the brain (+x is posterior).","name":"x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate of the channel location in the brain (+y is inferior).","name":"y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate of the channel location in the brain (+z is right).","name":"z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Impedance of the channel, in ohms.","name":"imp","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of hardware filtering, including the filter name and frequency cutoffs.","name":"filtering","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Reference to the ElectrodeGroup this electrode is a part of.","name":"group","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Name of the ElectrodeGroup this electrode is a part of.","name":"group_name","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"x coordinate in electrode group","name":"rel_x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate in electrode group","name":"rel_y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate in electrode group","name":"rel_z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of the reference electrode and/or reference scheme used for this electrode, e.g., \"stainless steel skull screw\" or \"online common average referencing\".","name":"reference","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"A table of all electrodes (i.e. channels) used for recording.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTable"}],"doc":"Metadata related to extracellular electrophysiology.","name":"extracellular_ephys","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"doc":"[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tabels. Additional SequentialRecordingsTable, RepetitionsTable and ExperimentalConditions tables provide enhanced support for experiment metadata.","name":"sweep_table","quantity":"?","neurodata_type_inc":"SweepTable"},{"doc":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response are recorded as as part of an experiment. In this case both, the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used.","name":"intracellular_recordings","quantity":"?","neurodata_type_inc":"IntracellularRecordingsTable"},{"doc":"A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes","name":"simultaneous_recordings","quantity":"?","neurodata_type_inc":"SimultaneousRecordingsTable"},{"doc":"A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where the a sequence of stimuli of the same type with varying parameters have been presented in a sequence.","name":"sequential_recordings","quantity":"?","neurodata_type_inc":"SequentialRecordingsTable"},{"doc":"A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence.","name":"repetitions","quantity":"?","neurodata_type_inc":"RepetitionsTable"},{"doc":"A table for grouping different intracellular recording repetitions together that belong to the same experimental experimental_conditions.","name":"experimental_conditions","quantity":"?","neurodata_type_inc":"ExperimentalConditionsTable"}],"datasets":[{"dtype":"text","doc":"[DEPRECATED] Use IntracellularElectrode.filtering instead. Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","name":"filtering","quantity":"?"}],"doc":"Metadata related to intracellular electrophysiology.","name":"intracellular_ephys","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"doc":"Metadata describing optogenetic stimuluation.","name":"optogenetics","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"doc":"Metadata related to optophysiology.","name":"optophysiology","quantity":"?"}],"datasets":[{"dtype":"text","doc":"Notes about data collection and analysis.","name":"data_collection","quantity":"?"},{"dtype":"text","doc":"General description of the experiment.","name":"experiment_description","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","name":"experimenter","quantity":"?"},{"dtype":"text","doc":"Institution(s) where experiment was performed.","name":"institution","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","doc":"Terms to search over.","name":"keywords","quantity":"?"},{"dtype":"text","doc":"Laboratory where experiment was performed.","name":"lab","quantity":"?"},{"dtype":"text","doc":"Notes about the experiment.","name":"notes","quantity":"?"},{"dtype":"text","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","name":"pharmacology","quantity":"?"},{"dtype":"text","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","name":"protocol","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","doc":"Publication information. PMID, DOI, URL, etc.","name":"related_publications","quantity":"?"},{"dtype":"text","doc":"Lab-specific ID for the session.","name":"session_id","quantity":"?"},{"dtype":"text","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","name":"slices","quantity":"?"},{"dtype":"text","doc":"Script file or link to public source code used to create this NWB file.","name":"source_script","quantity":"?","attributes":[{"doc":"Name of script file.","name":"file_name","dtype":"text"}]},{"dtype":"text","doc":"Notes about stimuli, such as how and where they were presented.","name":"stimulus","quantity":"?"},{"dtype":"text","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","name":"surgery","quantity":"?"},{"dtype":"text","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","name":"virus","quantity":"?"}],"doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them.","name":"general"},{"groups":[{"doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","name":"epochs","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Repeated experimental events that have a logical grouping.","name":"trials","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Time intervals that should be removed from analysis.","name":"invalid_times","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","name":"intervals","quantity":"?"},{"doc":"Data about sorted spike units.","name":"units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array.","name":"file_create_date"},{"dtype":"text","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files.","name":"identifier"},{"dtype":"text","doc":"A description of the experimental session and data in the file.","name":"session_description"},{"dtype":"isodatetime","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds.","name":"session_start_time"},{"dtype":"isodatetime","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).","name":"timestamps_reference_time"}],"doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","name":"root","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","name":"nwb_version","dtype":"text","value":"2.5.0"}]},{"doc":"Lab-specific meta-data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"datasets":[{"dtype":"text","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","name":"age","quantity":"?"},{"dtype":"isodatetime","doc":"Date of birth of subject. Can be supplied instead of 'age'.","name":"date_of_birth","quantity":"?"},{"dtype":"text","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","name":"description","quantity":"?"},{"dtype":"text","doc":"Genetic strain. If absent, assume Wild Type (WT).","name":"genotype","quantity":"?"},{"dtype":"text","doc":"Gender of subject.","name":"sex","quantity":"?"},{"dtype":"text","doc":"Species of subject.","name":"species","quantity":"?"},{"dtype":"text","doc":"Strain of subject.","name":"strain","quantity":"?"},{"dtype":"text","doc":"ID of animal/person used/participating in experiment (lab convention).","name":"subject_id","quantity":"?"},{"dtype":"text","doc":"Weight at time of experiment, at time of surgery and at other important times.","name":"weight","quantity":"?"}],"doc":"Information about the animal or person from which the data was measured.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"}]}~H{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"Values of each feature at each time.","name":"data","attributes":[{"doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","name":"unit","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Units of each feature.","name":"feature_units","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of the features represented in TimeSeries::data.","name":"features"}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","doc":"Annotations made during an experiment.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","doc":"Use values >0 if interval started, <0 if interval ended.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries"},{"groups":[{"datasets":[{"dtype":"text","doc":"Name of the band, e.g. theta.","name":"band_name","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float32","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","name":"band_limits","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The mean Gaussian filters, in Hz.","name":"band_mean","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The standard deviation of Gaussian filters, in Hz.","name":"band_stdev","neurodata_type_inc":"VectorData"}],"doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","name":"bands","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","doc":"Data decomposed into frequency bands.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"no unit"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"The metric used, e.g. phase, amplitude, power.","name":"metric"},{"doc":"DynamicTableRegion pointer to the channels that this decomposition series was generated from.","name":"source_channels","quantity":"?","neurodata_type_inc":"DynamicTableRegion"}],"links":[{"doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","name":"source_timeseries","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries"},{"datasets":[{"doc":"Index into the spike_times dataset.","name":"spike_times_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"float64","doc":"Spike times for each unit.","name":"spike_times","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"The smallest possible difference between two spike times. Usually 1 divided by the acquisition sampling rate from which spike times were extracted, but could be larger if the acquisition time series was downsampled or smaller if the acquisition time series was smoothed/interpolated and it is possible for the spike time to be between samples.","name":"resolution","required":false,"dtype":"float64"}]},{"doc":"Index into the obs_intervals dataset.","name":"obs_intervals_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"float64","doc":"Observation intervals for each unit.","name":"obs_intervals","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into electrodes.","name":"electrodes_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Electrode group that each spike unit came from.","name":"electrode_group","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform mean for each spike unit.","name":"waveform_mean","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform standard deviation for each spike unit.","name":"waveform_sd","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[null,null],"dims":["num_waveforms","num_samples"],"dtype":"numeric","doc":"Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.","name":"waveforms","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"doc":"Index into the waveforms dataset. One value for every spike event. See 'waveforms' for more detail.","name":"waveforms_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Index into the waveforms_index dataset. One value for every unit (row in the table). See 'waveforms' for more detail.","name":"waveforms_index_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units"}]}f{"groups":[{"datasets":[{"shape":[[null],[null,1],[null,2],[null,3]],"dims":[["num_times"],["num_times","x"],["num_times","x,y"],["num_times","x,y,z"]],"dtype":"numeric","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","required":false,"dtype":"text","default_value":"meters"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description defining what exactly 'straight-ahead' means.","name":"reference_frame","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries"},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]} {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Applied power for optogenetic stimulus, in watts.","name":"data","attributes":[{"doc":"Unit of measurement for data, which is fixed to 'watts'.","name":"unit","dtype":"text","value":"watts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","name":"site","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries"},{"datasets":[{"dtype":"text","doc":"Description of stimulation site.","name":"description"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"text","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"}],"links":[{"doc":"Device that generated the stimulus.","name":"device","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]}( ''SNOD(H08Xк'nwb.basenwb.devicenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespace'(GCOL<{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","doc":"Recorded voltage data.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion', followed by 'channel_conversion' (if present), and then add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float32","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","name":"channel_conversion","quantity":"?","attributes":[{"doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","name":"axis","dtype":"int32","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"doc":"Filtering applied to all channels of the data. For example, if this ElectricalSeries represents high-pass-filtered data (also known as AP Band), then this value could be \"High-pass 4-pole Bessel filter at 500 Hz\". If this ElectricalSeries represents low-pass-filtered LFP data and the type of filter is unknown, then this value could be \"Low-pass filter at 300 Hz\". If a non-standard filter type is used, provide as much detail about the filter properties as possible.","name":"filtering","required":false,"dtype":"text"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","doc":"Spike waveforms.","name":"data","attributes":[{"doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","name":"timestamps","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries"},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of features (eg, ''PC1'') for each of the extracted features.","name":"description"},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","doc":"Multi-dimensional array of features extracted from each event.","name":"features"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of events that features correspond to (can be a link).","name":"times"},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values.","name":"detection_method"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data.","name":"source_idx"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Timestamps of events, in seconds.","name":"times","attributes":[{"doc":"Unit of measurement for event times, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"links":[{"doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","name":"source_electricalseries","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"datasets":[{"dtype":[{"doc":"x coordinate","name":"x","dtype":"float32"},{"doc":"y coordinate","name":"y","dtype":"float32"},{"doc":"z coordinate","name":"z","dtype":"float32"}],"doc":"stereotaxic or common framework coordinates","name":"position","quantity":"?"}],"links":[{"doc":"Link to the device that was used to record from this electrode group.","name":"device","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"doc":"Description of this electrode group.","name":"description","dtype":"text"},{"doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, etc. Use standard atlas names for anatomical regions when possible.","name":"location","dtype":"text"}]},{"datasets":[{"dtype":"text","doc":"Filtering applied to data before generating mean/sd","name":"waveform_filtering"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)","name":"waveform_mean"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"Stdev of waveforms for each cluster, using the same indices as in mean","name":"waveform_sd"}],"links":[{"doc":"Link to Clustering interface that was the source of the clustered data","name":"clustering_interface","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)","name":"description"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Cluster number of each event","name":"num"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric).","name":"peak_over_rms"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module.","name":"times"}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}f{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Recorded voltage or current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","name":"gain","quantity":"?"}],"links":[{"doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","name":"electrode","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"doc":"Protocol/stimulus name for this patch-clamp dataset.","name":"stimulus_description","dtype":"text"},{"doc":"Sweep number, allows to group different PatchClampSeries together.","name":"sweep_number","required":false,"dtype":"uint32"}]},{"datasets":[{"doc":"Recorded voltage.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Bias current, in amps.","name":"bias_current","quantity":"?"},{"dtype":"float32","doc":"Bridge balance, in ohms.","name":"bridge_balance","quantity":"?"},{"dtype":"float32","doc":"Capacitance compensation, in farads.","name":"capacitance_compensation","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries"},{"datasets":[{"dtype":"float32","doc":"Bias current, in amps, fixed to 0.0.","name":"bias_current"},{"dtype":"float32","doc":"Bridge balance, in ohms, fixed to 0.0.","name":"bridge_balance"},{"dtype":"float32","doc":"Capacitance compensation, in farads, fixed to 0.0.","name":"capacitance_compensation"}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"doc":"An IZeroClampSeries has no stimulus, so this attribute is automatically set to \"N/A\"","name":"stimulus_description","dtype":"text","value":"N/A"}]},{"datasets":[{"doc":"Stimulus current applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries"},{"datasets":[{"doc":"Recorded current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Fast capacitance, in farads.","name":"capacitance_fast","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Slow capacitance, in farads.","name":"capacitance_slow","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Resistance compensation bandwidth, in hertz.","name":"resistance_comp_bandwidth","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","name":"unit","dtype":"text","value":"hertz"}]},{"dtype":"float32","doc":"Resistance compensation correction, in percent.","name":"resistance_comp_correction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Resistance compensation prediction, in percent.","name":"resistance_comp_prediction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Whole cell capacitance compensation, in farads.","name":"whole_cell_capacitance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Whole cell series resistance compensation, in ohms.","name":"whole_cell_series_resistance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","name":"unit","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries"},{"datasets":[{"doc":"Stimulus voltage applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries"},{"datasets":[{"dtype":"text","doc":"unique ID of the cell","name":"cell_id","quantity":"?"},{"dtype":"text","doc":"Description of electrode (e.g., whole-cell, sharp, etc.).","name":"description"},{"dtype":"text","doc":"Electrode specific filtering.","name":"filtering","quantity":"?"},{"dtype":"text","doc":"Initial access resistance.","name":"initial_access_resistance","quantity":"?"},{"dtype":"text","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","quantity":"?"},{"dtype":"text","doc":"Electrode resistance, in ohms.","name":"resistance","quantity":"?"},{"dtype":"text","doc":"Information about seal used for recording.","name":"seal","quantity":"?"},{"dtype":"text","doc":"Information about slice used for recording.","name":"slice","quantity":"?"}],"links":[{"doc":"Device that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint32","doc":"Sweep number of the PatchClampSeries in that row.","name":"sweep_number","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"doc":"The PatchClampSeries with the sweep number in that row.","name":"series","neurodata_type_inc":"VectorData"},{"doc":"Index for series.","name":"series_index","neurodata_type_inc":"VectorIndex"}],"doc":"[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tables. Additional SequentialRecordingsTable, RepetitionsTable, and ExperimentalConditions tables provide enhanced support for experiment metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable"},{"datasets":[{"dtype":{"target_type":"IntracellularElectrode","reftype":"object"},"doc":"Column for storing the reference to the intracellular electrode.","name":"electrode","neurodata_type_inc":"VectorData"}],"doc":"Table for storing intracellular electrode related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularElectrodesTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular electrode related metadata."}]},{"datasets":[{"doc":"Column storing the reference to the recorded stimulus for the recording (rows).","name":"stimulus","neurodata_type_inc":"TimeSeriesReferenceVectorData"}],"doc":"Table for storing intracellular stimulus related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularStimuliTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular stimulus related metadata."}]},{"datasets":[{"doc":"Column storing the reference to the recorded response for the recording (rows)","name":"response","neurodata_type_inc":"TimeSeriesReferenceVectorData"}],"doc":"Table for storing intracellular response related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularResponsesTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular response related metadata."}]},{"groups":[{"doc":"Table for storing intracellular electrode related metadata.","name":"electrodes","neurodata_type_inc":"IntracellularElectrodesTable"},{"doc":"Table for storing intracellular stimulus related metadata.","name":"stimuli","neurodata_type_inc":"IntracellularStimuliTable"},{"doc":"Table for storing intracellular response related metadata.","name":"responses","neurodata_type_inc":"IntracellularResponsesTable"}],"doc":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response is recorded as part of an experiment. In this case, both the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used.","name":"intracellular_recordings","neurodata_type_inc":"AlignedDynamicTable","neurodata_type_def":"IntracellularRecordingsTable","attributes":[{"doc":"Description of the contents of this table. Inherited from AlignedDynamicTable and overwritten here to fix the value of the attribute.","name":"description","dtype":"text","value":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording and for storing metadata about the intracellular recording."}]},{"datasets":[{"doc":"A reference to one or more rows in the IntracellularRecordingsTable table.","name":"recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the IntracellularRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"IntracellularRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the recordings column.","name":"recordings_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes.","name":"simultaneous_recordings","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SimultaneousRecordingsTable"},{"datasets":[{"doc":"A reference to one or more rows in the SimultaneousRecordingsTable table.","name":"simultaneous_recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the SimultaneousRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"SimultaneousRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the simultaneous_recordings column.","name":"simultaneous_recordings_index","neurodata_type_inc":"VectorIndex"},{"dtype":"text","doc":"The type of stimulus used for the sequential recording.","name":"stimulus_type","neurodata_type_inc":"VectorData"}],"doc":"A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where a sequence of stimuli of the same type with varying parameters have been presented in a sequence.","name":"sequential_recordings","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SequentialRecordingsTable"},{"datasets":[{"doc":"A reference to one or more rows in the SequentialRecordingsTable table.","name":"sequential_recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the SequentialRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"SequentialRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the sequential_recordings column.","name":"sequential_recordings_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence.","name":"repetitions","neurodata_type_inc":"DynamicTable","neurodata_type_def":"RepetitionsTable"},{"datasets":[{"doc":"A reference to one or more rows in the RepetitionsTable table.","name":"repetitions","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the RepetitionsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"RepetitionsTable","reftype":"object"}}]},{"doc":"Index dataset for the repetitions column.","name":"repetitions_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different intracellular recording repetitions together that belong to the same experimental condition.","name":"experimental_conditions","neurodata_type_inc":"DynamicTable","neurodata_type_def":"ExperimentalConditionsTable"}]}GCOL0h3{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"}],"links":[{"doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"doc":"Photomultiplier gain.","name":"pmt_gain","required":false,"dtype":"float32"},{"doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","name":"scan_line_rate","required":false,"dtype":"float32"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","doc":"Signals from ROIs.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","name":"rois","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. The first dimension represents time. The second dimension, if present, represents ROIs.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries"},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"PlaneSegmentation"}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"doc":"Image stacks that the segmentation masks apply to.","name":"reference_images"}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","name":"image_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into pixel_mask.","name":"pixel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float32"}],"doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"pixel_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into voxel_mask.","name":"voxel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint32"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float32"}],"doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"voxel_mask","quantity":"?","neurodata_type_inc":"VectorData"}],"links":[{"doc":"Link to ImagingPlane object from which this data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation"},{"groups":[{"doc":"An optical channel used to record from an imaging plane.","quantity":"+","neurodata_type_inc":"OpticalChannel"}],"datasets":[{"dtype":"text","doc":"Description of the imaging plane.","name":"description","quantity":"?"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"float32","doc":"Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead.","name":"imaging_rate","quantity":"?"},{"dtype":"text","doc":"Calcium indicator.","name":"indicator"},{"dtype":"text","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x, y, z"],["height","width","depth","x, y, z"]],"dtype":"float32","doc":"DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing.","name":"manifold","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Base unit of measurement for working with the data. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma).","name":"origin_coords","quantity":"?","attributes":[{"doc":"Measurement units for origin_coords. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid.","name":"grid_spacing","quantity":"?","attributes":[{"doc":"Measurement units for grid_spacing. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","doc":"Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = \"Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral).\"","name":"reference_frame","quantity":"?"}],"links":[{"doc":"Link to the Device object that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An imaging plane and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"datasets":[{"dtype":"text","doc":"Description or other notes about the channel.","name":"description"},{"dtype":"float32","doc":"Emission wavelength for channel, in nm.","name":"emission_lambda"}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"},{"groups":[{"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"},{"groups":[{"doc":"Image stack with frames shifted to the common coordinates.","name":"corrected","neurodata_type_inc":"ImageSeries"},{"doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","name":"xy_translation","neurodata_type_inc":"TimeSeries"}],"links":[{"doc":"Link to ImageSeries object that is being registered.","name":"original","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}]}x{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the first measured axis.","name":"axis_1_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_1_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the second measured axis.","name":"axis_2_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_2_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[2],"dims":["axis_1, axis_2"],"dtype":"text","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta'].","name":"axis_descriptions"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","name":"focal_depth_image","quantity":"?","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Focal depth offset, in meters.","name":"focal_depth","dtype":"float32"},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","name":"sign_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","name":"vasculature_image","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. This group does not store the raw responses imaged during retinotopic mapping or the stimuli presented, but rather the resulting phase and power maps after applying a Fourier transform on the averaged responses. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.device"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.5.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}(././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/2.1.0_imageseries_non_external_format.nwb0000644000175100001730000054400014467767506025563 0ustar00runnerdockerHDF  ` =hTREEH`CHEAP`B 0 .speclocx=HhTREE HEAPX test_imageseries8SNOD Hh0#X#x%P=HP:x:<!TREE@ (HEAPX8 dataexternal_fileformattimestamps SNOD(Pp  8 @ conversion ?@4 4? SNOD0 X h(x 8offset ?@4 4 @ resolution ?@4 4 @unitXGCOLunknown external_filetiffseconds no commentsno descriptioncore ImageSeries $1da96f17-17f5-4a5f-8220-71d3581190cf 2022-10-18T18:51:50.031752+00:00 ADDME ADDME 2022-10-18T18:51:50.031508+00:00 2022-10-18T18:51:50.031508+00:002.5.0coreNWBFile$ecd38088-ef9c-476c-9b68-1ed75d0974d0q{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"}],"groups":[{"doc":"An abstract data type for a group storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"groups":[{"doc":"Container objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Container"}],"datasets":[{"doc":"Data objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Data"}],"doc":"A simple Container for holding onto multiple containers.","data_type_inc":"Container","data_type_def":"SimpleMultiContainer"}]}N{"groups":[{"datasets":[{"shape":[null],"dims":["number of non-zero values"],"dtype":"uint","doc":"The column indices.","name":"indices"},{"shape":[null],"dims":["number of rows in the matrix + 1"],"dtype":"uint","doc":"The row index pointer.","name":"indptr"},{"shape":[null],"dims":["number of non-zero values"],"doc":"The non-zero values in the matrix.","name":"data"}],"doc":"A compressed sparse row matrix. Data are stored in the standard CSR format, where column indices for row i are stored in indices[indptr[i]:indptr[i+1]] and their corresponding values are stored in data[indptr[i]:indptr[i+1]].","data_type_inc":"Container","data_type_def":"CSRMatrix","attributes":[{"doc":"The shape (number of rows, number of columns) of this sparse matrix.","name":"shape","dtype":"uint","shape":[2],"dims":["number of rows, number of columns"]}]}]}Z{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"base"},{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.5.1","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"datasets":[{"dtype":"uint8","doc":"Data that come from a fixed set of values. A data value of i corresponds to the i-th value in the VectorData referenced by the 'elements' attribute.","data_type_inc":"VectorData","data_type_def":"EnumData","attributes":[{"doc":"Reference to the VectorData object that contains the enumerable elements","name":"elements","dtype":{"target_type":"VectorData","reftype":"object"}}]}]}{"groups":[{"datasets":[{"dtype":"float32","doc":"Start time of epoch, in seconds.","name":"start_time","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Stop time of epoch, in seconds.","name":"stop_time","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"User-defined tags that identify or categorize events.","name":"tags","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for tags.","name":"tags_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"An index into a TimeSeries object.","name":"timeseries","quantity":"?","neurodata_type_inc":"TimeSeriesReferenceVectorData"},{"doc":"Index for timeseries.","name":"timeseries_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals"}]}X& H starting_frame@8h& ?@4 4x& 8 interval@ @unitXPp H comments X H descriptionX H namespaceX Hneurodata_type X H object_id$X X#x%TREEHEAPX%PX.x003 XX?@@ X X X X XqXTNXZXX yyY"yX>/J~Hf< f  3^x^^TREEHEAPX0PTREEH6HEAPX(03presentationtemplates035TREEHEAPX5PSNOD33577979TREEHEAPX9Px:<TREEHEAPX<PE H nwb_versionXFH&&&&acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh>(%X.x0x?@x=FH8&03D&P H namespaceX Hneurodata_typeX H object_id$XTREELHEAPX8Ihdmf-commonhdmf-experimentalcore IKTREE PHEAPXK1.5.1HSNOD08XIIKooqMOTREExRHEAPX0Obasetablesparsenamespace(SNOD`MMO&SNODhQ nmS&GCOL{"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["dim0"],["dim0","dim1"],["dim0","dim1","dim2"],["dim0","dim1","dim2","dim3"]],"doc":"An n-dimensional dataset representing a column of a DynamicTable. If used without an accompanying VectorIndex, first dimension is along the rows of the DynamicTable and each step along the first dimension is a cell of the larger table. VectorData can also be used to represent a ragged array if paired with a VectorIndex. This allows for storing arrays of varying length in a single cell of the DynamicTable by indexing into this VectorData. The first vector is at VectorData[0:VectorIndex[0]]. The second vector is at VectorData[VectorIndex[0]:VectorIndex[1]], and so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"doc":"Description of what these vectors represent.","name":"description","dtype":"text"}]},{"shape":[null],"dims":["num_rows"],"dtype":"uint8","doc":"Used with VectorData to encode a ragged array. An array of indices into the first dimension of the target VectorData, and forming a map between the rows of a DynamicTable and the indices of the VectorData. The name of the VectorIndex is expected to be the name of the target VectorData object followed by \"_index\".","data_type_inc":"VectorData","data_type_def":"VectorIndex","attributes":[{"doc":"Reference to the target dataset that this index applies to.","name":"target","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"DynamicTableRegion provides a link from one table to an index or region of another. The `table` attribute is a link to another `DynamicTable`, indicating which table is referenced, and the data is int(s) indicating the row(s) (0-indexed) of the target array. `DynamicTableRegion`s can be used to associate rows with repeated meta-data without data duplication. They can also be used to create hierarchical relationships between multiple `DynamicTable`s. `DynamicTableRegion` objects may be paired with a `VectorIndex` object to create ragged references, so a single cell of a `DynamicTable` can reference many rows of another `DynamicTable`.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"doc":"Reference to the DynamicTable object that this region applies to.","name":"table","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"doc":"Description of what this table region points to.","name":"description","dtype":"text"}]}],"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"Array of unique identifiers for the rows of this dynamic table.","name":"id","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns, including index columns, of this dynamic table.","quantity":"*","data_type_inc":"VectorData"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). These datasets represent different columns in the table. Apart from a column that contains unique identifiers for each row, there are no other required datasets. Users are free to add any number of custom VectorData objects (columns) here. DynamicTable also supports ragged array columns, where each element can be of a different size. To add a ragged array column, use a VectorIndex type to index the corresponding VectorData type. See documentation for VectorData and VectorIndex for more details. Unlike a compound data type, which is analogous to storing an array-of-structs, a DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"doc":"The names of the columns in this table. This should be used to specify an order to the columns.","name":"colnames","dtype":"text","shape":[null],"dims":["num_columns"]},{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text"}]},{"groups":[{"doc":"A DynamicTable representing a particular category for columns in the AlignedDynamicTable parent container. The table MUST be aligned with (i.e., have the same number of rows) as all other DynamicTables stored in the AlignedDynamicTable parent container. The name of the category is given by the name of the DynamicTable and its description by the description attribute of the DynamicTable.","quantity":"*","data_type_inc":"DynamicTable"}],"doc":"DynamicTable container that supports storing a collection of sub-tables. Each sub-table is a DynamicTable itself that is aligned with the main table by row index. I.e., all DynamicTables stored in this group MUST have the same number of rows. This type effectively defines a 2-level table in which the main data is stored in the main table implemented by this type and additional columns of the table are grouped into categories, with each category being represented by a separate DynamicTable stored within the group.","data_type_inc":"DynamicTable","data_type_def":"AlignedDynamicTable","attributes":[{"doc":"The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.","name":"categories","dtype":"text","shape":[null],"dims":["num_categories"]}]}]}''oqTREE0uHEAPXr0.2.0HrtTREEwHEAPX8texperimentalresourcesnamespace SNODprrt 'SNODxv(x0'GCOL {"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The user term that maps to one or more resources in the 'resources' table.","name":"key","dtype":"text"}],"doc":"A table for storing user terms that are used to refer to external resources.","name":"keys","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the key in the 'keys' table.","name":"keys_idx","dtype":"uint"},{"doc":"The index into the 'resources' table","name":"resources_idx","dtype":"uint"},{"doc":"The unique identifier entity.","name":"entity_id","dtype":"text"},{"doc":"The URI for the entity this reference applies to. This can be an empty string.","name":"entity_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"entities","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The name of the resource.","name":"resource","dtype":"text"},{"doc":"The URI for the resource. This can be an empty string.","name":"resource_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"resources","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The UUID for the object.","name":"object_id","dtype":"text"},{"doc":"The relative path from the container with the object_id to the dataset or attribute with the value(s) that is associated with an external resource. This can be an empty string if the container is a dataset which contains the value(s) that is associated with an external resource.","name":"relative_path","dtype":"text"},{"doc":"The field of the compound data type using an external resource. This is used only if the dataset or attribute is a compound data type; otherwise this should be an empty string.","name":"field","dtype":"text"}],"doc":"A table for identifying which objects in a file contain references to external resources.","name":"objects","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the 'objects' table for the object that holds the key.","name":"objects_idx","dtype":"uint"},{"doc":"The index to the 'keys' table for the key.","name":"keys_idx","dtype":"uint"}],"doc":"A table for identifying which objects use which keys.","name":"object_keys","data_type_inc":"Data"}],"doc":"A set of four tables for tracking external resource references in a file. NOTE: this data type is in beta testing and is subject to change in a later version.","data_type_inc":"Container","data_type_def":"ExternalResources"}]}{"namespaces":[{"doc":"Experimental data structures provided by HDMF. These are not guaranteed to be available in the future.","schema":[{"namespace":"hdmf-common"},{"source":"experimental"},{"source":"resources"}],"name":"hdmf-experimental","full_name":"HDMF Experimental","version":"0.2.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Matthew Avaylon"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","mavaylon@lbl.gov"]}]}{"groups":[{"doc":"Metadata about a data acquisition device, e.g., recording system, electrode, microscope.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"doc":"Description of the device (e.g., model, firmware version, processing software version, etc.) as free-form text.","name":"description","required":false,"dtype":"text"},{"doc":"The name of the manufacturer of the device.","name":"manufacturer","required":false,"dtype":"text"}]}]}@'8TREEpHEAPXX2.5.0H؍TREEȒx@HEAP`SNOD؍P'SNODhx GCOL"Y"{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch","name":"count","dtype":"int32"},{"doc":"The TimeSeries that this index applies to","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"doc":"Column storing references to a TimeSeries (rows). For each TimeSeries this VectorData column stores the start_index and count to indicate the range in time to be selected as well as an object reference to the TimeSeries.","default_name":"timeseries","neurodata_type_inc":"VectorData","neurodata_type_def":"TimeSeriesReferenceVectorData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["x","y"],["x","y","r, g, b"],["x","y","r, g, b, a"]],"dtype":"numeric","doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"doc":"Pixel resolution of the image, in pixels per centimeter.","name":"resolution","required":false,"dtype":"float32"},{"doc":"Description of the image.","name":"description","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_images"],"dtype":{"target_type":"Image","reftype":"object"},"doc":"Ordered dataset of references to Image objects.","neurodata_type_inc":"NWBData","neurodata_type_def":"ImageReferences"}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","name":"sync","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float64","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","name":"starting_time","quantity":"?","attributes":[{"doc":"Sampling rate, in Hz.","name":"rate","dtype":"float32"},{"doc":"Unit of measurement for time, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","name":"timestamps","quantity":"?","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","name":"control","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","name":"control_description","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"doc":"Description of the time series.","name":"description","required":false,"dtype":"text","default_value":"no description"},{"doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","name":"comments","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"doc":"Description of this collection of processed data.","name":"description","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"},{"doc":"Ordered dataset of references to Image objects stored in the parent group. Each Image object in the Images group should be stored once and only once, so the dataset should have the same length as the number of images.","name":"order_of_images","quantity":"?","neurodata_type_inc":"ImageReferences"}],"doc":"A collection of images with an optional way to specify the order of the images using the \"order_of_images\" dataset. An order must be specified if the images are referenced by index, e.g., from an IndexSeries.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"doc":"Description of this collection of images.","name":"description","dtype":"text"}]}]}`'p'''''GCOL>/{"datasets":[{"shape":[null,null],"dims":["x","y"],"dtype":"numeric","doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage"},{"shape":[null,null,3],"dims":["x","y","r, g, b"],"dtype":"numeric","doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage"},{"shape":[null,null,4],"dims":["x","y","r, g, b, a"],"dtype":"numeric","doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage"}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","x","y"],["frame","x","y","z"]],"dtype":"numeric","doc":"Binary data representing images across frames. If data are stored in an external file, this should be an empty 3D array.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","doc":"Number of pixels on x, y, (and z) axes.","name":"dimension","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","name":"external_file","quantity":"?","attributes":[{"doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","name":"starting_frame","dtype":"int32","shape":[null],"dims":["num_files"]}]},{"dtype":"text","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","name":"format","quantity":"?","default_value":"raw"}],"links":[{"doc":"Link to the Device object that was used to capture these images.","name":"device","target_type":"Device","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][x][y] or [frame][x][y][z].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries"},{"links":[{"doc":"Link to ImageSeries object that this image mask is applied to.","name":"masked_imageseries","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries"},{"datasets":[{"dtype":"float32","doc":"Distance from camera/monitor to target/eye.","name":"distance","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"},{"shape":[[null,null,null],[null,null,null,3]],"dims":[["frame","x","y"],["frame","x","y","r, g, b"]],"dtype":"numeric","doc":"Images presented to subject, either grayscale or RGB","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","name":"orientation","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"uint32","doc":"Index of the image (using zero-indexing) in the linked Images object.","name":"data","attributes":[{"doc":"This field is unused by IndexSeries.","name":"conversion","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries.","name":"resolution","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries.","name":"offset","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries and has the value N/A.","name":"unit","dtype":"text","value":"N/A"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to ImageSeries object containing images that are indexed. Use of this link is discouraged and will be deprecated. Link to an Images type instead.","name":"indexed_timeseries","target_type":"ImageSeries","quantity":"?"},{"doc":"Link to Images object containing an ordered set of images that are indexed. The Images object must contain a 'ordered_images' dataset specifying the order of the images in the Images type.","name":"indexed_images","target_type":"Images","quantity":"?"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the IndexSeries is to allow a static image stack to be stored in an Images object, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced Images object, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries"}]}J{"datasets":[{"doc":"Any one-off datasets","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"doc":"Any notes the user has about the dataset being stored","name":"notes","dtype":"text"}]}],"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.","name":"acquisition"},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.","name":"analysis"},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"ScratchData"}],"doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","name":"scratch","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.","name":"processing"},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Stimuli presented during the experiment.","name":"presentation"},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"},{"doc":"Images objects containing images of presented stimuli.","quantity":"*","neurodata_type_inc":"Images"}],"doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.","name":"templates"}],"doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file.","name":"stimulus"},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"LabMetaData"},{"groups":[{"doc":"Data acquisition devices.","quantity":"*","neurodata_type_inc":"Device"}],"doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","name":"devices","quantity":"?"},{"doc":"Information about the animal or person from which the data was measured.","name":"subject","quantity":"?","neurodata_type_inc":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float32","doc":"x coordinate of the channel location in the brain (+x is posterior).","name":"x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate of the channel location in the brain (+y is inferior).","name":"y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate of the channel location in the brain (+z is right).","name":"z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Impedance of the channel, in ohms.","name":"imp","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of hardware filtering, including the filter name and frequency cutoffs.","name":"filtering","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Reference to the ElectrodeGroup this electrode is a part of.","name":"group","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Name of the ElectrodeGroup this electrode is a part of.","name":"group_name","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"x coordinate in electrode group","name":"rel_x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate in electrode group","name":"rel_y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate in electrode group","name":"rel_z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of the reference electrode and/or reference scheme used for this electrode, e.g., \"stainless steel skull screw\" or \"online common average referencing\".","name":"reference","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"A table of all electrodes (i.e. channels) used for recording.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTable"}],"doc":"Metadata related to extracellular electrophysiology.","name":"extracellular_ephys","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"doc":"[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tabels. Additional SequentialRecordingsTable, RepetitionsTable and ExperimentalConditions tables provide enhanced support for experiment metadata.","name":"sweep_table","quantity":"?","neurodata_type_inc":"SweepTable"},{"doc":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response are recorded as as part of an experiment. In this case both, the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used.","name":"intracellular_recordings","quantity":"?","neurodata_type_inc":"IntracellularRecordingsTable"},{"doc":"A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes","name":"simultaneous_recordings","quantity":"?","neurodata_type_inc":"SimultaneousRecordingsTable"},{"doc":"A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where the a sequence of stimuli of the same type with varying parameters have been presented in a sequence.","name":"sequential_recordings","quantity":"?","neurodata_type_inc":"SequentialRecordingsTable"},{"doc":"A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence.","name":"repetitions","quantity":"?","neurodata_type_inc":"RepetitionsTable"},{"doc":"A table for grouping different intracellular recording repetitions together that belong to the same experimental experimental_conditions.","name":"experimental_conditions","quantity":"?","neurodata_type_inc":"ExperimentalConditionsTable"}],"datasets":[{"dtype":"text","doc":"[DEPRECATED] Use IntracellularElectrode.filtering instead. Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","name":"filtering","quantity":"?"}],"doc":"Metadata related to intracellular electrophysiology.","name":"intracellular_ephys","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"doc":"Metadata describing optogenetic stimuluation.","name":"optogenetics","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"doc":"Metadata related to optophysiology.","name":"optophysiology","quantity":"?"}],"datasets":[{"dtype":"text","doc":"Notes about data collection and analysis.","name":"data_collection","quantity":"?"},{"dtype":"text","doc":"General description of the experiment.","name":"experiment_description","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","name":"experimenter","quantity":"?"},{"dtype":"text","doc":"Institution(s) where experiment was performed.","name":"institution","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","doc":"Terms to search over.","name":"keywords","quantity":"?"},{"dtype":"text","doc":"Laboratory where experiment was performed.","name":"lab","quantity":"?"},{"dtype":"text","doc":"Notes about the experiment.","name":"notes","quantity":"?"},{"dtype":"text","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","name":"pharmacology","quantity":"?"},{"dtype":"text","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","name":"protocol","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","doc":"Publication information. PMID, DOI, URL, etc.","name":"related_publications","quantity":"?"},{"dtype":"text","doc":"Lab-specific ID for the session.","name":"session_id","quantity":"?"},{"dtype":"text","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","name":"slices","quantity":"?"},{"dtype":"text","doc":"Script file or link to public source code used to create this NWB file.","name":"source_script","quantity":"?","attributes":[{"doc":"Name of script file.","name":"file_name","dtype":"text"}]},{"dtype":"text","doc":"Notes about stimuli, such as how and where they were presented.","name":"stimulus","quantity":"?"},{"dtype":"text","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","name":"surgery","quantity":"?"},{"dtype":"text","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","name":"virus","quantity":"?"}],"doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them.","name":"general"},{"groups":[{"doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","name":"epochs","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Repeated experimental events that have a logical grouping.","name":"trials","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Time intervals that should be removed from analysis.","name":"invalid_times","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","name":"intervals","quantity":"?"},{"doc":"Data about sorted spike units.","name":"units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array.","name":"file_create_date"},{"dtype":"text","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files.","name":"identifier"},{"dtype":"text","doc":"A description of the experimental session and data in the file.","name":"session_description"},{"dtype":"isodatetime","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds.","name":"session_start_time"},{"dtype":"isodatetime","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).","name":"timestamps_reference_time"}],"doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","name":"root","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","name":"nwb_version","dtype":"text","value":"2.5.0"}]},{"doc":"Lab-specific meta-data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"datasets":[{"dtype":"text","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","name":"age","quantity":"?"},{"dtype":"isodatetime","doc":"Date of birth of subject. Can be supplied instead of 'age'.","name":"date_of_birth","quantity":"?"},{"dtype":"text","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","name":"description","quantity":"?"},{"dtype":"text","doc":"Genetic strain. If absent, assume Wild Type (WT).","name":"genotype","quantity":"?"},{"dtype":"text","doc":"Gender of subject.","name":"sex","quantity":"?"},{"dtype":"text","doc":"Species of subject.","name":"species","quantity":"?"},{"dtype":"text","doc":"Strain of subject.","name":"strain","quantity":"?"},{"dtype":"text","doc":"ID of animal/person used/participating in experiment (lab convention).","name":"subject_id","quantity":"?"},{"dtype":"text","doc":"Weight at time of experiment, at time of surgery and at other important times.","name":"weight","quantity":"?"}],"doc":"Information about the animal or person from which the data was measured.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"}]}~H{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"Values of each feature at each time.","name":"data","attributes":[{"doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","name":"unit","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Units of each feature.","name":"feature_units","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of the features represented in TimeSeries::data.","name":"features"}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","doc":"Annotations made during an experiment.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","doc":"Use values >0 if interval started, <0 if interval ended.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries"},{"groups":[{"datasets":[{"dtype":"text","doc":"Name of the band, e.g. theta.","name":"band_name","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float32","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","name":"band_limits","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The mean Gaussian filters, in Hz.","name":"band_mean","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The standard deviation of Gaussian filters, in Hz.","name":"band_stdev","neurodata_type_inc":"VectorData"}],"doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","name":"bands","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","doc":"Data decomposed into frequency bands.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"no unit"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"The metric used, e.g. phase, amplitude, power.","name":"metric"},{"doc":"DynamicTableRegion pointer to the channels that this decomposition series was generated from.","name":"source_channels","quantity":"?","neurodata_type_inc":"DynamicTableRegion"}],"links":[{"doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","name":"source_timeseries","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries"},{"datasets":[{"doc":"Index into the spike_times dataset.","name":"spike_times_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"float64","doc":"Spike times for each unit.","name":"spike_times","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"The smallest possible difference between two spike times. Usually 1 divided by the acquisition sampling rate from which spike times were extracted, but could be larger if the acquisition time series was downsampled or smaller if the acquisition time series was smoothed/interpolated and it is possible for the spike time to be between samples.","name":"resolution","required":false,"dtype":"float64"}]},{"doc":"Index into the obs_intervals dataset.","name":"obs_intervals_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"float64","doc":"Observation intervals for each unit.","name":"obs_intervals","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into electrodes.","name":"electrodes_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Electrode group that each spike unit came from.","name":"electrode_group","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform mean for each spike unit.","name":"waveform_mean","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform standard deviation for each spike unit.","name":"waveform_sd","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[null,null],"dims":["num_waveforms","num_samples"],"dtype":"numeric","doc":"Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.","name":"waveforms","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"doc":"Index into the waveforms dataset. One value for every spike event. See 'waveforms' for more detail.","name":"waveforms_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Index into the waveforms_index dataset. One value for every unit (row in the table). See 'waveforms' for more detail.","name":"waveforms_index_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units"}]}f{"groups":[{"datasets":[{"shape":[[null],[null,1],[null,2],[null,3]],"dims":[["num_times"],["num_times","x"],["num_times","x,y"],["num_times","x,y,z"]],"dtype":"numeric","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","required":false,"dtype":"text","default_value":"meters"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description defining what exactly 'straight-ahead' means.","name":"reference_frame","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries"},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]} {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Applied power for optogenetic stimulus, in watts.","name":"data","attributes":[{"doc":"Unit of measurement for data, which is fixed to 'watts'.","name":"unit","dtype":"text","value":"watts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","name":"site","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries"},{"datasets":[{"dtype":"text","doc":"Description of stimulation site.","name":"description"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"text","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"}],"links":[{"doc":"Device that generated the stimulus.","name":"device","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]}( ''SNOD(H08Xк'nwb.basenwb.devicenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespace'(GCOL<{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","doc":"Recorded voltage data.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion', followed by 'channel_conversion' (if present), and then add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float32","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","name":"channel_conversion","quantity":"?","attributes":[{"doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","name":"axis","dtype":"int32","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"doc":"Filtering applied to all channels of the data. For example, if this ElectricalSeries represents high-pass-filtered data (also known as AP Band), then this value could be \"High-pass 4-pole Bessel filter at 500 Hz\". If this ElectricalSeries represents low-pass-filtered LFP data and the type of filter is unknown, then this value could be \"Low-pass filter at 300 Hz\". If a non-standard filter type is used, provide as much detail about the filter properties as possible.","name":"filtering","required":false,"dtype":"text"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","doc":"Spike waveforms.","name":"data","attributes":[{"doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","name":"timestamps","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries"},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of features (eg, ''PC1'') for each of the extracted features.","name":"description"},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","doc":"Multi-dimensional array of features extracted from each event.","name":"features"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of events that features correspond to (can be a link).","name":"times"},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values.","name":"detection_method"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data.","name":"source_idx"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Timestamps of events, in seconds.","name":"times","attributes":[{"doc":"Unit of measurement for event times, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"links":[{"doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","name":"source_electricalseries","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"datasets":[{"dtype":[{"doc":"x coordinate","name":"x","dtype":"float32"},{"doc":"y coordinate","name":"y","dtype":"float32"},{"doc":"z coordinate","name":"z","dtype":"float32"}],"doc":"stereotaxic or common framework coordinates","name":"position","quantity":"?"}],"links":[{"doc":"Link to the device that was used to record from this electrode group.","name":"device","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"doc":"Description of this electrode group.","name":"description","dtype":"text"},{"doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, etc. Use standard atlas names for anatomical regions when possible.","name":"location","dtype":"text"}]},{"datasets":[{"dtype":"text","doc":"Filtering applied to data before generating mean/sd","name":"waveform_filtering"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)","name":"waveform_mean"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"Stdev of waveforms for each cluster, using the same indices as in mean","name":"waveform_sd"}],"links":[{"doc":"Link to Clustering interface that was the source of the clustered data","name":"clustering_interface","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)","name":"description"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Cluster number of each event","name":"num"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric).","name":"peak_over_rms"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module.","name":"times"}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}f{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Recorded voltage or current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","name":"gain","quantity":"?"}],"links":[{"doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","name":"electrode","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"doc":"Protocol/stimulus name for this patch-clamp dataset.","name":"stimulus_description","dtype":"text"},{"doc":"Sweep number, allows to group different PatchClampSeries together.","name":"sweep_number","required":false,"dtype":"uint32"}]},{"datasets":[{"doc":"Recorded voltage.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Bias current, in amps.","name":"bias_current","quantity":"?"},{"dtype":"float32","doc":"Bridge balance, in ohms.","name":"bridge_balance","quantity":"?"},{"dtype":"float32","doc":"Capacitance compensation, in farads.","name":"capacitance_compensation","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries"},{"datasets":[{"dtype":"float32","doc":"Bias current, in amps, fixed to 0.0.","name":"bias_current"},{"dtype":"float32","doc":"Bridge balance, in ohms, fixed to 0.0.","name":"bridge_balance"},{"dtype":"float32","doc":"Capacitance compensation, in farads, fixed to 0.0.","name":"capacitance_compensation"}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"doc":"An IZeroClampSeries has no stimulus, so this attribute is automatically set to \"N/A\"","name":"stimulus_description","dtype":"text","value":"N/A"}]},{"datasets":[{"doc":"Stimulus current applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries"},{"datasets":[{"doc":"Recorded current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Fast capacitance, in farads.","name":"capacitance_fast","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Slow capacitance, in farads.","name":"capacitance_slow","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Resistance compensation bandwidth, in hertz.","name":"resistance_comp_bandwidth","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","name":"unit","dtype":"text","value":"hertz"}]},{"dtype":"float32","doc":"Resistance compensation correction, in percent.","name":"resistance_comp_correction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Resistance compensation prediction, in percent.","name":"resistance_comp_prediction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Whole cell capacitance compensation, in farads.","name":"whole_cell_capacitance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Whole cell series resistance compensation, in ohms.","name":"whole_cell_series_resistance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","name":"unit","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries"},{"datasets":[{"doc":"Stimulus voltage applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries"},{"datasets":[{"dtype":"text","doc":"unique ID of the cell","name":"cell_id","quantity":"?"},{"dtype":"text","doc":"Description of electrode (e.g., whole-cell, sharp, etc.).","name":"description"},{"dtype":"text","doc":"Electrode specific filtering.","name":"filtering","quantity":"?"},{"dtype":"text","doc":"Initial access resistance.","name":"initial_access_resistance","quantity":"?"},{"dtype":"text","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","quantity":"?"},{"dtype":"text","doc":"Electrode resistance, in ohms.","name":"resistance","quantity":"?"},{"dtype":"text","doc":"Information about seal used for recording.","name":"seal","quantity":"?"},{"dtype":"text","doc":"Information about slice used for recording.","name":"slice","quantity":"?"}],"links":[{"doc":"Device that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint32","doc":"Sweep number of the PatchClampSeries in that row.","name":"sweep_number","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"doc":"The PatchClampSeries with the sweep number in that row.","name":"series","neurodata_type_inc":"VectorData"},{"doc":"Index for series.","name":"series_index","neurodata_type_inc":"VectorIndex"}],"doc":"[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tables. Additional SequentialRecordingsTable, RepetitionsTable, and ExperimentalConditions tables provide enhanced support for experiment metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable"},{"datasets":[{"dtype":{"target_type":"IntracellularElectrode","reftype":"object"},"doc":"Column for storing the reference to the intracellular electrode.","name":"electrode","neurodata_type_inc":"VectorData"}],"doc":"Table for storing intracellular electrode related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularElectrodesTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular electrode related metadata."}]},{"datasets":[{"doc":"Column storing the reference to the recorded stimulus for the recording (rows).","name":"stimulus","neurodata_type_inc":"TimeSeriesReferenceVectorData"}],"doc":"Table for storing intracellular stimulus related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularStimuliTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular stimulus related metadata."}]},{"datasets":[{"doc":"Column storing the reference to the recorded response for the recording (rows)","name":"response","neurodata_type_inc":"TimeSeriesReferenceVectorData"}],"doc":"Table for storing intracellular response related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularResponsesTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular response related metadata."}]},{"groups":[{"doc":"Table for storing intracellular electrode related metadata.","name":"electrodes","neurodata_type_inc":"IntracellularElectrodesTable"},{"doc":"Table for storing intracellular stimulus related metadata.","name":"stimuli","neurodata_type_inc":"IntracellularStimuliTable"},{"doc":"Table for storing intracellular response related metadata.","name":"responses","neurodata_type_inc":"IntracellularResponsesTable"}],"doc":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response is recorded as part of an experiment. In this case, both the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used.","name":"intracellular_recordings","neurodata_type_inc":"AlignedDynamicTable","neurodata_type_def":"IntracellularRecordingsTable","attributes":[{"doc":"Description of the contents of this table. Inherited from AlignedDynamicTable and overwritten here to fix the value of the attribute.","name":"description","dtype":"text","value":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording and for storing metadata about the intracellular recording."}]},{"datasets":[{"doc":"A reference to one or more rows in the IntracellularRecordingsTable table.","name":"recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the IntracellularRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"IntracellularRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the recordings column.","name":"recordings_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes.","name":"simultaneous_recordings","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SimultaneousRecordingsTable"},{"datasets":[{"doc":"A reference to one or more rows in the SimultaneousRecordingsTable table.","name":"simultaneous_recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the SimultaneousRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"SimultaneousRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the simultaneous_recordings column.","name":"simultaneous_recordings_index","neurodata_type_inc":"VectorIndex"},{"dtype":"text","doc":"The type of stimulus used for the sequential recording.","name":"stimulus_type","neurodata_type_inc":"VectorData"}],"doc":"A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where a sequence of stimuli of the same type with varying parameters have been presented in a sequence.","name":"sequential_recordings","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SequentialRecordingsTable"},{"datasets":[{"doc":"A reference to one or more rows in the SequentialRecordingsTable table.","name":"sequential_recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the SequentialRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"SequentialRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the sequential_recordings column.","name":"sequential_recordings_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence.","name":"repetitions","neurodata_type_inc":"DynamicTable","neurodata_type_def":"RepetitionsTable"},{"datasets":[{"doc":"A reference to one or more rows in the RepetitionsTable table.","name":"repetitions","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the RepetitionsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"RepetitionsTable","reftype":"object"}}]},{"doc":"Index dataset for the repetitions column.","name":"repetitions_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different intracellular recording repetitions together that belong to the same experimental condition.","name":"experimental_conditions","neurodata_type_inc":"DynamicTable","neurodata_type_def":"ExperimentalConditionsTable"}]}GCOL0h3{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"}],"links":[{"doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"doc":"Photomultiplier gain.","name":"pmt_gain","required":false,"dtype":"float32"},{"doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","name":"scan_line_rate","required":false,"dtype":"float32"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","doc":"Signals from ROIs.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","name":"rois","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. The first dimension represents time. The second dimension, if present, represents ROIs.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries"},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"PlaneSegmentation"}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"doc":"Image stacks that the segmentation masks apply to.","name":"reference_images"}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","name":"image_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into pixel_mask.","name":"pixel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float32"}],"doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"pixel_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into voxel_mask.","name":"voxel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint32"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float32"}],"doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"voxel_mask","quantity":"?","neurodata_type_inc":"VectorData"}],"links":[{"doc":"Link to ImagingPlane object from which this data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation"},{"groups":[{"doc":"An optical channel used to record from an imaging plane.","quantity":"+","neurodata_type_inc":"OpticalChannel"}],"datasets":[{"dtype":"text","doc":"Description of the imaging plane.","name":"description","quantity":"?"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"float32","doc":"Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead.","name":"imaging_rate","quantity":"?"},{"dtype":"text","doc":"Calcium indicator.","name":"indicator"},{"dtype":"text","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x, y, z"],["height","width","depth","x, y, z"]],"dtype":"float32","doc":"DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing.","name":"manifold","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Base unit of measurement for working with the data. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma).","name":"origin_coords","quantity":"?","attributes":[{"doc":"Measurement units for origin_coords. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid.","name":"grid_spacing","quantity":"?","attributes":[{"doc":"Measurement units for grid_spacing. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","doc":"Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = \"Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral).\"","name":"reference_frame","quantity":"?"}],"links":[{"doc":"Link to the Device object that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An imaging plane and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"datasets":[{"dtype":"text","doc":"Description or other notes about the channel.","name":"description"},{"dtype":"float32","doc":"Emission wavelength for channel, in nm.","name":"emission_lambda"}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"},{"groups":[{"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"},{"groups":[{"doc":"Image stack with frames shifted to the common coordinates.","name":"corrected","neurodata_type_inc":"ImageSeries"},{"doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","name":"xy_translation","neurodata_type_inc":"TimeSeries"}],"links":[{"doc":"Link to ImageSeries object that is being registered.","name":"original","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}]}x{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the first measured axis.","name":"axis_1_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_1_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the second measured axis.","name":"axis_2_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_2_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[2],"dims":["axis_1, axis_2"],"dtype":"text","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta'].","name":"axis_descriptions"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","name":"focal_depth_image","quantity":"?","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Focal depth offset, in meters.","name":"focal_depth","dtype":"float32"},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","name":"sign_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","name":"vasculature_image","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. This group does not store the raw responses imaged during retinotopic mapping or the stimuli presented, but rather the resulting phase and power maps after applying a Fourier transform on the averaged responses. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.device"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.5.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}(././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/2.1.0_imageseries_nonmatch_starting_frame.nwb0000644000175100001730000054400014467767506026413 0ustar00runnerdockerHDF  ` =hTREEH`CHEAP`B 0 .speclocx=HhTREE HEAPX test_imageseries8SNOD Hh0#X#x%P=HP:x:<!TREE@ (HEAPX8 dataexternal_fileformattimestamps SNOD(Pp  8 @ conversion ?@4 4? SNOD0 X h(x 8offset ?@4 4 @ resolution ?@4 4 @unitXGCOLunknown external_fileexternalseconds no commentsno descriptioncore ImageSeries $aa0ded42-4f6d-4c7f-a6b9-617b7c4dacbc 2022-10-18T18:51:50.768626+00:00 ADDME ADDME 2022-10-18T18:51:50.768377+00:00 2022-10-18T18:51:50.768377+00:002.5.0coreNWBFile$b55d7529-adc0-4147-ace0-56519e925cbaq{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"}],"groups":[{"doc":"An abstract data type for a group storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"groups":[{"doc":"Container objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Container"}],"datasets":[{"doc":"Data objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Data"}],"doc":"A simple Container for holding onto multiple containers.","data_type_inc":"Container","data_type_def":"SimpleMultiContainer"}]}N{"groups":[{"datasets":[{"shape":[null],"dims":["number of non-zero values"],"dtype":"uint","doc":"The column indices.","name":"indices"},{"shape":[null],"dims":["number of rows in the matrix + 1"],"dtype":"uint","doc":"The row index pointer.","name":"indptr"},{"shape":[null],"dims":["number of non-zero values"],"doc":"The non-zero values in the matrix.","name":"data"}],"doc":"A compressed sparse row matrix. Data are stored in the standard CSR format, where column indices for row i are stored in indices[indptr[i]:indptr[i+1]] and their corresponding values are stored in data[indptr[i]:indptr[i+1]].","data_type_inc":"Container","data_type_def":"CSRMatrix","attributes":[{"doc":"The shape (number of rows, number of columns) of this sparse matrix.","name":"shape","dtype":"uint","shape":[2],"dims":["number of rows, number of columns"]}]}]}Z{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"base"},{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.5.1","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"datasets":[{"dtype":"uint8","doc":"Data that come from a fixed set of values. A data value of i corresponds to the i-th value in the VectorData referenced by the 'elements' attribute.","data_type_inc":"VectorData","data_type_def":"EnumData","attributes":[{"doc":"Reference to the VectorData object that contains the enumerable elements","name":"elements","dtype":{"target_type":"VectorData","reftype":"object"}}]}]}{"groups":[{"datasets":[{"dtype":"float32","doc":"Start time of epoch, in seconds.","name":"start_time","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Stop time of epoch, in seconds.","name":"stop_time","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"User-defined tags that identify or categorize events.","name":"tags","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for tags.","name":"tags_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"An index into a TimeSeries object.","name":"timeseries","quantity":"?","neurodata_type_inc":"TimeSeriesReferenceVectorData"},{"doc":"Index for timeseries.","name":"timeseries_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals"}]}X& X starting_frame@(h& ?@4 4x& 8 interval@ @unitXPp H comments X H descriptionX H namespaceX Hneurodata_type X H object_id$X X#x%TREEHEAPX%PX.x003 XX?@@ X X X X XqXTNXZXX yyY"yX>/J~Hf< f  3^x^^TREEHEAPX0PTREEH6HEAPX(03presentationtemplates035TREEHEAPX5PSNOD33577979TREEHEAPX9Px:<TREEHEAPX<PE H nwb_versionXFH&&&&acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh>(%X.x0x?@x=FH8&03D&P H namespaceX Hneurodata_typeX H object_id$XTREELHEAPX8Ihdmf-commonhdmf-experimentalcore IKTREE PHEAPXK1.5.1HSNOD08XIIKooqMOTREExRHEAPX0Obasetablesparsenamespace(SNOD`MMO&SNODhQ nmS&GCOL{"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["dim0"],["dim0","dim1"],["dim0","dim1","dim2"],["dim0","dim1","dim2","dim3"]],"doc":"An n-dimensional dataset representing a column of a DynamicTable. If used without an accompanying VectorIndex, first dimension is along the rows of the DynamicTable and each step along the first dimension is a cell of the larger table. VectorData can also be used to represent a ragged array if paired with a VectorIndex. This allows for storing arrays of varying length in a single cell of the DynamicTable by indexing into this VectorData. The first vector is at VectorData[0:VectorIndex[0]]. The second vector is at VectorData[VectorIndex[0]:VectorIndex[1]], and so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"doc":"Description of what these vectors represent.","name":"description","dtype":"text"}]},{"shape":[null],"dims":["num_rows"],"dtype":"uint8","doc":"Used with VectorData to encode a ragged array. An array of indices into the first dimension of the target VectorData, and forming a map between the rows of a DynamicTable and the indices of the VectorData. The name of the VectorIndex is expected to be the name of the target VectorData object followed by \"_index\".","data_type_inc":"VectorData","data_type_def":"VectorIndex","attributes":[{"doc":"Reference to the target dataset that this index applies to.","name":"target","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"DynamicTableRegion provides a link from one table to an index or region of another. The `table` attribute is a link to another `DynamicTable`, indicating which table is referenced, and the data is int(s) indicating the row(s) (0-indexed) of the target array. `DynamicTableRegion`s can be used to associate rows with repeated meta-data without data duplication. They can also be used to create hierarchical relationships between multiple `DynamicTable`s. `DynamicTableRegion` objects may be paired with a `VectorIndex` object to create ragged references, so a single cell of a `DynamicTable` can reference many rows of another `DynamicTable`.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"doc":"Reference to the DynamicTable object that this region applies to.","name":"table","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"doc":"Description of what this table region points to.","name":"description","dtype":"text"}]}],"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"Array of unique identifiers for the rows of this dynamic table.","name":"id","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns, including index columns, of this dynamic table.","quantity":"*","data_type_inc":"VectorData"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). These datasets represent different columns in the table. Apart from a column that contains unique identifiers for each row, there are no other required datasets. Users are free to add any number of custom VectorData objects (columns) here. DynamicTable also supports ragged array columns, where each element can be of a different size. To add a ragged array column, use a VectorIndex type to index the corresponding VectorData type. See documentation for VectorData and VectorIndex for more details. Unlike a compound data type, which is analogous to storing an array-of-structs, a DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"doc":"The names of the columns in this table. This should be used to specify an order to the columns.","name":"colnames","dtype":"text","shape":[null],"dims":["num_columns"]},{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text"}]},{"groups":[{"doc":"A DynamicTable representing a particular category for columns in the AlignedDynamicTable parent container. The table MUST be aligned with (i.e., have the same number of rows) as all other DynamicTables stored in the AlignedDynamicTable parent container. The name of the category is given by the name of the DynamicTable and its description by the description attribute of the DynamicTable.","quantity":"*","data_type_inc":"DynamicTable"}],"doc":"DynamicTable container that supports storing a collection of sub-tables. Each sub-table is a DynamicTable itself that is aligned with the main table by row index. I.e., all DynamicTables stored in this group MUST have the same number of rows. This type effectively defines a 2-level table in which the main data is stored in the main table implemented by this type and additional columns of the table are grouped into categories, with each category being represented by a separate DynamicTable stored within the group.","data_type_inc":"DynamicTable","data_type_def":"AlignedDynamicTable","attributes":[{"doc":"The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.","name":"categories","dtype":"text","shape":[null],"dims":["num_categories"]}]}]}''oqTREE0uHEAPXr0.2.0HrtTREEwHEAPX8texperimentalresourcesnamespace SNODprrt 'SNODxv(x0'GCOL {"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The user term that maps to one or more resources in the 'resources' table.","name":"key","dtype":"text"}],"doc":"A table for storing user terms that are used to refer to external resources.","name":"keys","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the key in the 'keys' table.","name":"keys_idx","dtype":"uint"},{"doc":"The index into the 'resources' table","name":"resources_idx","dtype":"uint"},{"doc":"The unique identifier entity.","name":"entity_id","dtype":"text"},{"doc":"The URI for the entity this reference applies to. This can be an empty string.","name":"entity_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"entities","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The name of the resource.","name":"resource","dtype":"text"},{"doc":"The URI for the resource. This can be an empty string.","name":"resource_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"resources","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The UUID for the object.","name":"object_id","dtype":"text"},{"doc":"The relative path from the container with the object_id to the dataset or attribute with the value(s) that is associated with an external resource. This can be an empty string if the container is a dataset which contains the value(s) that is associated with an external resource.","name":"relative_path","dtype":"text"},{"doc":"The field of the compound data type using an external resource. This is used only if the dataset or attribute is a compound data type; otherwise this should be an empty string.","name":"field","dtype":"text"}],"doc":"A table for identifying which objects in a file contain references to external resources.","name":"objects","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the 'objects' table for the object that holds the key.","name":"objects_idx","dtype":"uint"},{"doc":"The index to the 'keys' table for the key.","name":"keys_idx","dtype":"uint"}],"doc":"A table for identifying which objects use which keys.","name":"object_keys","data_type_inc":"Data"}],"doc":"A set of four tables for tracking external resource references in a file. NOTE: this data type is in beta testing and is subject to change in a later version.","data_type_inc":"Container","data_type_def":"ExternalResources"}]}{"namespaces":[{"doc":"Experimental data structures provided by HDMF. These are not guaranteed to be available in the future.","schema":[{"namespace":"hdmf-common"},{"source":"experimental"},{"source":"resources"}],"name":"hdmf-experimental","full_name":"HDMF Experimental","version":"0.2.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Matthew Avaylon"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","mavaylon@lbl.gov"]}]}{"groups":[{"doc":"Metadata about a data acquisition device, e.g., recording system, electrode, microscope.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"doc":"Description of the device (e.g., model, firmware version, processing software version, etc.) as free-form text.","name":"description","required":false,"dtype":"text"},{"doc":"The name of the manufacturer of the device.","name":"manufacturer","required":false,"dtype":"text"}]}]}@'8TREEpHEAPXX2.5.0H؍TREEȒx@HEAP`SNOD؍P'SNODhx GCOL"Y"{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch","name":"count","dtype":"int32"},{"doc":"The TimeSeries that this index applies to","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"doc":"Column storing references to a TimeSeries (rows). For each TimeSeries this VectorData column stores the start_index and count to indicate the range in time to be selected as well as an object reference to the TimeSeries.","default_name":"timeseries","neurodata_type_inc":"VectorData","neurodata_type_def":"TimeSeriesReferenceVectorData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["x","y"],["x","y","r, g, b"],["x","y","r, g, b, a"]],"dtype":"numeric","doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"doc":"Pixel resolution of the image, in pixels per centimeter.","name":"resolution","required":false,"dtype":"float32"},{"doc":"Description of the image.","name":"description","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_images"],"dtype":{"target_type":"Image","reftype":"object"},"doc":"Ordered dataset of references to Image objects.","neurodata_type_inc":"NWBData","neurodata_type_def":"ImageReferences"}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","name":"sync","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float64","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","name":"starting_time","quantity":"?","attributes":[{"doc":"Sampling rate, in Hz.","name":"rate","dtype":"float32"},{"doc":"Unit of measurement for time, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","name":"timestamps","quantity":"?","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","name":"control","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","name":"control_description","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"doc":"Description of the time series.","name":"description","required":false,"dtype":"text","default_value":"no description"},{"doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","name":"comments","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"doc":"Description of this collection of processed data.","name":"description","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"},{"doc":"Ordered dataset of references to Image objects stored in the parent group. Each Image object in the Images group should be stored once and only once, so the dataset should have the same length as the number of images.","name":"order_of_images","quantity":"?","neurodata_type_inc":"ImageReferences"}],"doc":"A collection of images with an optional way to specify the order of the images using the \"order_of_images\" dataset. An order must be specified if the images are referenced by index, e.g., from an IndexSeries.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"doc":"Description of this collection of images.","name":"description","dtype":"text"}]}]}`'p'''''GCOL>/{"datasets":[{"shape":[null,null],"dims":["x","y"],"dtype":"numeric","doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage"},{"shape":[null,null,3],"dims":["x","y","r, g, b"],"dtype":"numeric","doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage"},{"shape":[null,null,4],"dims":["x","y","r, g, b, a"],"dtype":"numeric","doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage"}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","x","y"],["frame","x","y","z"]],"dtype":"numeric","doc":"Binary data representing images across frames. If data are stored in an external file, this should be an empty 3D array.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","doc":"Number of pixels on x, y, (and z) axes.","name":"dimension","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","name":"external_file","quantity":"?","attributes":[{"doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","name":"starting_frame","dtype":"int32","shape":[null],"dims":["num_files"]}]},{"dtype":"text","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","name":"format","quantity":"?","default_value":"raw"}],"links":[{"doc":"Link to the Device object that was used to capture these images.","name":"device","target_type":"Device","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][x][y] or [frame][x][y][z].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries"},{"links":[{"doc":"Link to ImageSeries object that this image mask is applied to.","name":"masked_imageseries","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries"},{"datasets":[{"dtype":"float32","doc":"Distance from camera/monitor to target/eye.","name":"distance","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"},{"shape":[[null,null,null],[null,null,null,3]],"dims":[["frame","x","y"],["frame","x","y","r, g, b"]],"dtype":"numeric","doc":"Images presented to subject, either grayscale or RGB","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","name":"orientation","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"uint32","doc":"Index of the image (using zero-indexing) in the linked Images object.","name":"data","attributes":[{"doc":"This field is unused by IndexSeries.","name":"conversion","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries.","name":"resolution","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries.","name":"offset","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries and has the value N/A.","name":"unit","dtype":"text","value":"N/A"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to ImageSeries object containing images that are indexed. Use of this link is discouraged and will be deprecated. Link to an Images type instead.","name":"indexed_timeseries","target_type":"ImageSeries","quantity":"?"},{"doc":"Link to Images object containing an ordered set of images that are indexed. The Images object must contain a 'ordered_images' dataset specifying the order of the images in the Images type.","name":"indexed_images","target_type":"Images","quantity":"?"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the IndexSeries is to allow a static image stack to be stored in an Images object, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced Images object, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries"}]}J{"datasets":[{"doc":"Any one-off datasets","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"doc":"Any notes the user has about the dataset being stored","name":"notes","dtype":"text"}]}],"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.","name":"acquisition"},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.","name":"analysis"},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"ScratchData"}],"doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","name":"scratch","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.","name":"processing"},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Stimuli presented during the experiment.","name":"presentation"},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"},{"doc":"Images objects containing images of presented stimuli.","quantity":"*","neurodata_type_inc":"Images"}],"doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.","name":"templates"}],"doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file.","name":"stimulus"},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"LabMetaData"},{"groups":[{"doc":"Data acquisition devices.","quantity":"*","neurodata_type_inc":"Device"}],"doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","name":"devices","quantity":"?"},{"doc":"Information about the animal or person from which the data was measured.","name":"subject","quantity":"?","neurodata_type_inc":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float32","doc":"x coordinate of the channel location in the brain (+x is posterior).","name":"x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate of the channel location in the brain (+y is inferior).","name":"y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate of the channel location in the brain (+z is right).","name":"z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Impedance of the channel, in ohms.","name":"imp","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of hardware filtering, including the filter name and frequency cutoffs.","name":"filtering","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Reference to the ElectrodeGroup this electrode is a part of.","name":"group","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Name of the ElectrodeGroup this electrode is a part of.","name":"group_name","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"x coordinate in electrode group","name":"rel_x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate in electrode group","name":"rel_y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate in electrode group","name":"rel_z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of the reference electrode and/or reference scheme used for this electrode, e.g., \"stainless steel skull screw\" or \"online common average referencing\".","name":"reference","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"A table of all electrodes (i.e. channels) used for recording.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTable"}],"doc":"Metadata related to extracellular electrophysiology.","name":"extracellular_ephys","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"doc":"[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tabels. Additional SequentialRecordingsTable, RepetitionsTable and ExperimentalConditions tables provide enhanced support for experiment metadata.","name":"sweep_table","quantity":"?","neurodata_type_inc":"SweepTable"},{"doc":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response are recorded as as part of an experiment. In this case both, the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used.","name":"intracellular_recordings","quantity":"?","neurodata_type_inc":"IntracellularRecordingsTable"},{"doc":"A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes","name":"simultaneous_recordings","quantity":"?","neurodata_type_inc":"SimultaneousRecordingsTable"},{"doc":"A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where the a sequence of stimuli of the same type with varying parameters have been presented in a sequence.","name":"sequential_recordings","quantity":"?","neurodata_type_inc":"SequentialRecordingsTable"},{"doc":"A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence.","name":"repetitions","quantity":"?","neurodata_type_inc":"RepetitionsTable"},{"doc":"A table for grouping different intracellular recording repetitions together that belong to the same experimental experimental_conditions.","name":"experimental_conditions","quantity":"?","neurodata_type_inc":"ExperimentalConditionsTable"}],"datasets":[{"dtype":"text","doc":"[DEPRECATED] Use IntracellularElectrode.filtering instead. Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","name":"filtering","quantity":"?"}],"doc":"Metadata related to intracellular electrophysiology.","name":"intracellular_ephys","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"doc":"Metadata describing optogenetic stimuluation.","name":"optogenetics","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"doc":"Metadata related to optophysiology.","name":"optophysiology","quantity":"?"}],"datasets":[{"dtype":"text","doc":"Notes about data collection and analysis.","name":"data_collection","quantity":"?"},{"dtype":"text","doc":"General description of the experiment.","name":"experiment_description","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","name":"experimenter","quantity":"?"},{"dtype":"text","doc":"Institution(s) where experiment was performed.","name":"institution","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","doc":"Terms to search over.","name":"keywords","quantity":"?"},{"dtype":"text","doc":"Laboratory where experiment was performed.","name":"lab","quantity":"?"},{"dtype":"text","doc":"Notes about the experiment.","name":"notes","quantity":"?"},{"dtype":"text","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","name":"pharmacology","quantity":"?"},{"dtype":"text","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","name":"protocol","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","doc":"Publication information. PMID, DOI, URL, etc.","name":"related_publications","quantity":"?"},{"dtype":"text","doc":"Lab-specific ID for the session.","name":"session_id","quantity":"?"},{"dtype":"text","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","name":"slices","quantity":"?"},{"dtype":"text","doc":"Script file or link to public source code used to create this NWB file.","name":"source_script","quantity":"?","attributes":[{"doc":"Name of script file.","name":"file_name","dtype":"text"}]},{"dtype":"text","doc":"Notes about stimuli, such as how and where they were presented.","name":"stimulus","quantity":"?"},{"dtype":"text","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","name":"surgery","quantity":"?"},{"dtype":"text","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","name":"virus","quantity":"?"}],"doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them.","name":"general"},{"groups":[{"doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","name":"epochs","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Repeated experimental events that have a logical grouping.","name":"trials","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Time intervals that should be removed from analysis.","name":"invalid_times","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","name":"intervals","quantity":"?"},{"doc":"Data about sorted spike units.","name":"units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array.","name":"file_create_date"},{"dtype":"text","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files.","name":"identifier"},{"dtype":"text","doc":"A description of the experimental session and data in the file.","name":"session_description"},{"dtype":"isodatetime","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds.","name":"session_start_time"},{"dtype":"isodatetime","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).","name":"timestamps_reference_time"}],"doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","name":"root","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","name":"nwb_version","dtype":"text","value":"2.5.0"}]},{"doc":"Lab-specific meta-data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"datasets":[{"dtype":"text","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","name":"age","quantity":"?"},{"dtype":"isodatetime","doc":"Date of birth of subject. Can be supplied instead of 'age'.","name":"date_of_birth","quantity":"?"},{"dtype":"text","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","name":"description","quantity":"?"},{"dtype":"text","doc":"Genetic strain. If absent, assume Wild Type (WT).","name":"genotype","quantity":"?"},{"dtype":"text","doc":"Gender of subject.","name":"sex","quantity":"?"},{"dtype":"text","doc":"Species of subject.","name":"species","quantity":"?"},{"dtype":"text","doc":"Strain of subject.","name":"strain","quantity":"?"},{"dtype":"text","doc":"ID of animal/person used/participating in experiment (lab convention).","name":"subject_id","quantity":"?"},{"dtype":"text","doc":"Weight at time of experiment, at time of surgery and at other important times.","name":"weight","quantity":"?"}],"doc":"Information about the animal or person from which the data was measured.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"}]}~H{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"Values of each feature at each time.","name":"data","attributes":[{"doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","name":"unit","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Units of each feature.","name":"feature_units","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of the features represented in TimeSeries::data.","name":"features"}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","doc":"Annotations made during an experiment.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","doc":"Use values >0 if interval started, <0 if interval ended.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries"},{"groups":[{"datasets":[{"dtype":"text","doc":"Name of the band, e.g. theta.","name":"band_name","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float32","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","name":"band_limits","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The mean Gaussian filters, in Hz.","name":"band_mean","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The standard deviation of Gaussian filters, in Hz.","name":"band_stdev","neurodata_type_inc":"VectorData"}],"doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","name":"bands","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","doc":"Data decomposed into frequency bands.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"no unit"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"The metric used, e.g. phase, amplitude, power.","name":"metric"},{"doc":"DynamicTableRegion pointer to the channels that this decomposition series was generated from.","name":"source_channels","quantity":"?","neurodata_type_inc":"DynamicTableRegion"}],"links":[{"doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","name":"source_timeseries","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries"},{"datasets":[{"doc":"Index into the spike_times dataset.","name":"spike_times_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"float64","doc":"Spike times for each unit.","name":"spike_times","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"The smallest possible difference between two spike times. Usually 1 divided by the acquisition sampling rate from which spike times were extracted, but could be larger if the acquisition time series was downsampled or smaller if the acquisition time series was smoothed/interpolated and it is possible for the spike time to be between samples.","name":"resolution","required":false,"dtype":"float64"}]},{"doc":"Index into the obs_intervals dataset.","name":"obs_intervals_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"float64","doc":"Observation intervals for each unit.","name":"obs_intervals","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into electrodes.","name":"electrodes_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Electrode group that each spike unit came from.","name":"electrode_group","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform mean for each spike unit.","name":"waveform_mean","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform standard deviation for each spike unit.","name":"waveform_sd","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[null,null],"dims":["num_waveforms","num_samples"],"dtype":"numeric","doc":"Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.","name":"waveforms","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"doc":"Index into the waveforms dataset. One value for every spike event. See 'waveforms' for more detail.","name":"waveforms_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Index into the waveforms_index dataset. One value for every unit (row in the table). See 'waveforms' for more detail.","name":"waveforms_index_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units"}]}f{"groups":[{"datasets":[{"shape":[[null],[null,1],[null,2],[null,3]],"dims":[["num_times"],["num_times","x"],["num_times","x,y"],["num_times","x,y,z"]],"dtype":"numeric","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","required":false,"dtype":"text","default_value":"meters"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description defining what exactly 'straight-ahead' means.","name":"reference_frame","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries"},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]} {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Applied power for optogenetic stimulus, in watts.","name":"data","attributes":[{"doc":"Unit of measurement for data, which is fixed to 'watts'.","name":"unit","dtype":"text","value":"watts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","name":"site","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries"},{"datasets":[{"dtype":"text","doc":"Description of stimulation site.","name":"description"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"text","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"}],"links":[{"doc":"Device that generated the stimulus.","name":"device","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]}( ''SNOD(H08Xк'nwb.basenwb.devicenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespace'(GCOL<{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","doc":"Recorded voltage data.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion', followed by 'channel_conversion' (if present), and then add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float32","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","name":"channel_conversion","quantity":"?","attributes":[{"doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","name":"axis","dtype":"int32","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"doc":"Filtering applied to all channels of the data. For example, if this ElectricalSeries represents high-pass-filtered data (also known as AP Band), then this value could be \"High-pass 4-pole Bessel filter at 500 Hz\". If this ElectricalSeries represents low-pass-filtered LFP data and the type of filter is unknown, then this value could be \"Low-pass filter at 300 Hz\". If a non-standard filter type is used, provide as much detail about the filter properties as possible.","name":"filtering","required":false,"dtype":"text"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","doc":"Spike waveforms.","name":"data","attributes":[{"doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","name":"timestamps","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries"},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of features (eg, ''PC1'') for each of the extracted features.","name":"description"},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","doc":"Multi-dimensional array of features extracted from each event.","name":"features"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of events that features correspond to (can be a link).","name":"times"},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values.","name":"detection_method"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data.","name":"source_idx"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Timestamps of events, in seconds.","name":"times","attributes":[{"doc":"Unit of measurement for event times, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"links":[{"doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","name":"source_electricalseries","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"datasets":[{"dtype":[{"doc":"x coordinate","name":"x","dtype":"float32"},{"doc":"y coordinate","name":"y","dtype":"float32"},{"doc":"z coordinate","name":"z","dtype":"float32"}],"doc":"stereotaxic or common framework coordinates","name":"position","quantity":"?"}],"links":[{"doc":"Link to the device that was used to record from this electrode group.","name":"device","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"doc":"Description of this electrode group.","name":"description","dtype":"text"},{"doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, etc. Use standard atlas names for anatomical regions when possible.","name":"location","dtype":"text"}]},{"datasets":[{"dtype":"text","doc":"Filtering applied to data before generating mean/sd","name":"waveform_filtering"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)","name":"waveform_mean"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"Stdev of waveforms for each cluster, using the same indices as in mean","name":"waveform_sd"}],"links":[{"doc":"Link to Clustering interface that was the source of the clustered data","name":"clustering_interface","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)","name":"description"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Cluster number of each event","name":"num"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric).","name":"peak_over_rms"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module.","name":"times"}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}f{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Recorded voltage or current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","name":"gain","quantity":"?"}],"links":[{"doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","name":"electrode","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"doc":"Protocol/stimulus name for this patch-clamp dataset.","name":"stimulus_description","dtype":"text"},{"doc":"Sweep number, allows to group different PatchClampSeries together.","name":"sweep_number","required":false,"dtype":"uint32"}]},{"datasets":[{"doc":"Recorded voltage.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Bias current, in amps.","name":"bias_current","quantity":"?"},{"dtype":"float32","doc":"Bridge balance, in ohms.","name":"bridge_balance","quantity":"?"},{"dtype":"float32","doc":"Capacitance compensation, in farads.","name":"capacitance_compensation","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries"},{"datasets":[{"dtype":"float32","doc":"Bias current, in amps, fixed to 0.0.","name":"bias_current"},{"dtype":"float32","doc":"Bridge balance, in ohms, fixed to 0.0.","name":"bridge_balance"},{"dtype":"float32","doc":"Capacitance compensation, in farads, fixed to 0.0.","name":"capacitance_compensation"}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"doc":"An IZeroClampSeries has no stimulus, so this attribute is automatically set to \"N/A\"","name":"stimulus_description","dtype":"text","value":"N/A"}]},{"datasets":[{"doc":"Stimulus current applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries"},{"datasets":[{"doc":"Recorded current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Fast capacitance, in farads.","name":"capacitance_fast","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Slow capacitance, in farads.","name":"capacitance_slow","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Resistance compensation bandwidth, in hertz.","name":"resistance_comp_bandwidth","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","name":"unit","dtype":"text","value":"hertz"}]},{"dtype":"float32","doc":"Resistance compensation correction, in percent.","name":"resistance_comp_correction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Resistance compensation prediction, in percent.","name":"resistance_comp_prediction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Whole cell capacitance compensation, in farads.","name":"whole_cell_capacitance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Whole cell series resistance compensation, in ohms.","name":"whole_cell_series_resistance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","name":"unit","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries"},{"datasets":[{"doc":"Stimulus voltage applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries"},{"datasets":[{"dtype":"text","doc":"unique ID of the cell","name":"cell_id","quantity":"?"},{"dtype":"text","doc":"Description of electrode (e.g., whole-cell, sharp, etc.).","name":"description"},{"dtype":"text","doc":"Electrode specific filtering.","name":"filtering","quantity":"?"},{"dtype":"text","doc":"Initial access resistance.","name":"initial_access_resistance","quantity":"?"},{"dtype":"text","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","quantity":"?"},{"dtype":"text","doc":"Electrode resistance, in ohms.","name":"resistance","quantity":"?"},{"dtype":"text","doc":"Information about seal used for recording.","name":"seal","quantity":"?"},{"dtype":"text","doc":"Information about slice used for recording.","name":"slice","quantity":"?"}],"links":[{"doc":"Device that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint32","doc":"Sweep number of the PatchClampSeries in that row.","name":"sweep_number","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"doc":"The PatchClampSeries with the sweep number in that row.","name":"series","neurodata_type_inc":"VectorData"},{"doc":"Index for series.","name":"series_index","neurodata_type_inc":"VectorIndex"}],"doc":"[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tables. Additional SequentialRecordingsTable, RepetitionsTable, and ExperimentalConditions tables provide enhanced support for experiment metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable"},{"datasets":[{"dtype":{"target_type":"IntracellularElectrode","reftype":"object"},"doc":"Column for storing the reference to the intracellular electrode.","name":"electrode","neurodata_type_inc":"VectorData"}],"doc":"Table for storing intracellular electrode related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularElectrodesTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular electrode related metadata."}]},{"datasets":[{"doc":"Column storing the reference to the recorded stimulus for the recording (rows).","name":"stimulus","neurodata_type_inc":"TimeSeriesReferenceVectorData"}],"doc":"Table for storing intracellular stimulus related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularStimuliTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular stimulus related metadata."}]},{"datasets":[{"doc":"Column storing the reference to the recorded response for the recording (rows)","name":"response","neurodata_type_inc":"TimeSeriesReferenceVectorData"}],"doc":"Table for storing intracellular response related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularResponsesTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular response related metadata."}]},{"groups":[{"doc":"Table for storing intracellular electrode related metadata.","name":"electrodes","neurodata_type_inc":"IntracellularElectrodesTable"},{"doc":"Table for storing intracellular stimulus related metadata.","name":"stimuli","neurodata_type_inc":"IntracellularStimuliTable"},{"doc":"Table for storing intracellular response related metadata.","name":"responses","neurodata_type_inc":"IntracellularResponsesTable"}],"doc":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response is recorded as part of an experiment. In this case, both the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used.","name":"intracellular_recordings","neurodata_type_inc":"AlignedDynamicTable","neurodata_type_def":"IntracellularRecordingsTable","attributes":[{"doc":"Description of the contents of this table. Inherited from AlignedDynamicTable and overwritten here to fix the value of the attribute.","name":"description","dtype":"text","value":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording and for storing metadata about the intracellular recording."}]},{"datasets":[{"doc":"A reference to one or more rows in the IntracellularRecordingsTable table.","name":"recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the IntracellularRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"IntracellularRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the recordings column.","name":"recordings_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes.","name":"simultaneous_recordings","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SimultaneousRecordingsTable"},{"datasets":[{"doc":"A reference to one or more rows in the SimultaneousRecordingsTable table.","name":"simultaneous_recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the SimultaneousRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"SimultaneousRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the simultaneous_recordings column.","name":"simultaneous_recordings_index","neurodata_type_inc":"VectorIndex"},{"dtype":"text","doc":"The type of stimulus used for the sequential recording.","name":"stimulus_type","neurodata_type_inc":"VectorData"}],"doc":"A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where a sequence of stimuli of the same type with varying parameters have been presented in a sequence.","name":"sequential_recordings","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SequentialRecordingsTable"},{"datasets":[{"doc":"A reference to one or more rows in the SequentialRecordingsTable table.","name":"sequential_recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the SequentialRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"SequentialRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the sequential_recordings column.","name":"sequential_recordings_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence.","name":"repetitions","neurodata_type_inc":"DynamicTable","neurodata_type_def":"RepetitionsTable"},{"datasets":[{"doc":"A reference to one or more rows in the RepetitionsTable table.","name":"repetitions","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the RepetitionsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"RepetitionsTable","reftype":"object"}}]},{"doc":"Index dataset for the repetitions column.","name":"repetitions_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different intracellular recording repetitions together that belong to the same experimental condition.","name":"experimental_conditions","neurodata_type_inc":"DynamicTable","neurodata_type_def":"ExperimentalConditionsTable"}]}GCOL0h3{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"}],"links":[{"doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"doc":"Photomultiplier gain.","name":"pmt_gain","required":false,"dtype":"float32"},{"doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","name":"scan_line_rate","required":false,"dtype":"float32"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","doc":"Signals from ROIs.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","name":"rois","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. The first dimension represents time. The second dimension, if present, represents ROIs.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries"},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"PlaneSegmentation"}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"doc":"Image stacks that the segmentation masks apply to.","name":"reference_images"}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","name":"image_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into pixel_mask.","name":"pixel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float32"}],"doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"pixel_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into voxel_mask.","name":"voxel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint32"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float32"}],"doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"voxel_mask","quantity":"?","neurodata_type_inc":"VectorData"}],"links":[{"doc":"Link to ImagingPlane object from which this data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation"},{"groups":[{"doc":"An optical channel used to record from an imaging plane.","quantity":"+","neurodata_type_inc":"OpticalChannel"}],"datasets":[{"dtype":"text","doc":"Description of the imaging plane.","name":"description","quantity":"?"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"float32","doc":"Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead.","name":"imaging_rate","quantity":"?"},{"dtype":"text","doc":"Calcium indicator.","name":"indicator"},{"dtype":"text","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x, y, z"],["height","width","depth","x, y, z"]],"dtype":"float32","doc":"DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing.","name":"manifold","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Base unit of measurement for working with the data. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma).","name":"origin_coords","quantity":"?","attributes":[{"doc":"Measurement units for origin_coords. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid.","name":"grid_spacing","quantity":"?","attributes":[{"doc":"Measurement units for grid_spacing. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","doc":"Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = \"Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral).\"","name":"reference_frame","quantity":"?"}],"links":[{"doc":"Link to the Device object that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An imaging plane and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"datasets":[{"dtype":"text","doc":"Description or other notes about the channel.","name":"description"},{"dtype":"float32","doc":"Emission wavelength for channel, in nm.","name":"emission_lambda"}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"},{"groups":[{"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"},{"groups":[{"doc":"Image stack with frames shifted to the common coordinates.","name":"corrected","neurodata_type_inc":"ImageSeries"},{"doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","name":"xy_translation","neurodata_type_inc":"TimeSeries"}],"links":[{"doc":"Link to ImageSeries object that is being registered.","name":"original","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}]}x{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the first measured axis.","name":"axis_1_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_1_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the second measured axis.","name":"axis_2_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_2_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[2],"dims":["axis_1, axis_2"],"dtype":"text","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta'].","name":"axis_descriptions"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","name":"focal_depth_image","quantity":"?","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Focal depth offset, in meters.","name":"focal_depth","dtype":"float32"},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","name":"sign_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","name":"vasculature_image","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. This group does not store the raw responses imaged during retinotopic mapping or the stimuli presented, but rather the resulting phase and power maps after applying a Fourier transform on the averaged responses. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.device"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.5.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}(././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/2.1.0_nwbfile_with_extension.nwb0000644000175100001730000054753014467767506023732 0ustar00runnerdockerHDF  X` ;hTREEHPAHEAP`? 0 .specloch;HhTREE HEAPXtest_tsHSNOD Hh(PpP;H@8h8:HTREE@ HEAPX datastarting_time8SNOD(Pp   ?@4 4  @ conversion ?@4 4? 8offset ?@4 4SNOD0 8?@@     qRNZ wwY"w>/J~Hf<f 3\x\\\\ @ resolution ?@4 4 @unit ?@4 4  8rate ?@4 4? @unitPp H comments  H description 0 id@ H namespace Hneurodata_type H object_id$PpTREEHEAPXP-HEAPX0P/HEAPX(presentationtemplates01357GCOLADDMEseconds no commentsADDMEndx-testextensionTimeSeriesWithID$93be7d5f-7397-4e78-a8ec-f0f95c6f6e34 2022-09-20T23:07:44.417243+00:00 ADDME ADDME 2022-09-20T23:07:44.416980+00:00 2022-09-20T23:07:44.416980+00:00 2.5.0coreNWBFile$d7b218bc-1b2e-424e-ba56-75e07c4a7458q{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"}],"groups":[{"doc":"An abstract data type for a group storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"groups":[{"doc":"Container objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Container"}],"datasets":[{"doc":"Data objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Data"}],"doc":"A simple Container for holding onto multiple containers.","data_type_inc":"Container","data_type_def":"SimpleMultiContainer"}]}N{"groups":[{"datasets":[{"shape":[null],"dims":["number of non-zero values"],"dtype":"uint","doc":"The column indices.","name":"indices"},{"shape":[null],"dims":["number of rows in the matrix + 1"],"dtype":"uint","doc":"The row index pointer.","name":"indptr"},{"shape":[null],"dims":["number of non-zero values"],"doc":"The non-zero values in the matrix.","name":"data"}],"doc":"A compressed sparse row matrix. Data are stored in the standard CSR format, where column indices for row i are stored in indices[indptr[i]:indptr[i+1]] and their corresponding values are stored in data[indptr[i]:indptr[i+1]].","data_type_inc":"Container","data_type_def":"CSRMatrix","attributes":[{"doc":"The shape (number of rows, number of columns) of this sparse matrix.","name":"shape","dtype":"uint","shape":[2],"dims":["number of rows, number of columns"]}]}]}Z{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"base"},{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.5.1","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"datasets":[{"dtype":"uint8","doc":"Data that come from a fixed set of values. A data value of i corresponds to the i-th value in the VectorData referenced by the 'elements' attribute.","data_type_inc":"VectorData","data_type_def":"EnumData","attributes":[{"doc":"Reference to the VectorData object that contains the enumerable elements","name":"elements","dtype":{"target_type":"VectorData","reftype":"object"}}]}]}{"groups":[{"datasets":[{"dtype":"float32","doc":"Start time of epoch, in seconds.","name":"start_time","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Stop time of epoch, in seconds.","name":"stop_time","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"User-defined tags that identify or categorize events.","name":"tags","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for tags.","name":"tags_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"An index into a TimeSeries object.","name":"timeseries","quantity":"?","neurodata_type_inc":"TimeSeriesReferenceVectorData"},{"doc":"Index for timeseries.","name":"timeseries_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals"}]} TREETREE`4TREEHEAPX4PSNOD(13P57TREEHEAPX7Ph8:TREEHEAPX:PC H nwb_version DF    acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh<(-x=>h;DF8/B P H namespace Hneurodata_type H object_id$TREEJ8HEAPPpGITREENHEAPXI1.5.1HSNOD0(HGpGImmo8йxKMTREEhPHEAPX0Mbasetablesparsenamespace(SNODPKxKM SNODXO lkQGCOL{"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["dim0"],["dim0","dim1"],["dim0","dim1","dim2"],["dim0","dim1","dim2","dim3"]],"doc":"An n-dimensional dataset representing a column of a DynamicTable. If used without an accompanying VectorIndex, first dimension is along the rows of the DynamicTable and each step along the first dimension is a cell of the larger table. VectorData can also be used to represent a ragged array if paired with a VectorIndex. This allows for storing arrays of varying length in a single cell of the DynamicTable by indexing into this VectorData. The first vector is at VectorData[0:VectorIndex[0]]. The second vector is at VectorData[VectorIndex[0]:VectorIndex[1]], and so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"doc":"Description of what these vectors represent.","name":"description","dtype":"text"}]},{"shape":[null],"dims":["num_rows"],"dtype":"uint8","doc":"Used with VectorData to encode a ragged array. An array of indices into the first dimension of the target VectorData, and forming a map between the rows of a DynamicTable and the indices of the VectorData. The name of the VectorIndex is expected to be the name of the target VectorData object followed by \"_index\".","data_type_inc":"VectorData","data_type_def":"VectorIndex","attributes":[{"doc":"Reference to the target dataset that this index applies to.","name":"target","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"DynamicTableRegion provides a link from one table to an index or region of another. The `table` attribute is a link to another `DynamicTable`, indicating which table is referenced, and the data is int(s) indicating the row(s) (0-indexed) of the target array. `DynamicTableRegion`s can be used to associate rows with repeated meta-data without data duplication. They can also be used to create hierarchical relationships between multiple `DynamicTable`s. `DynamicTableRegion` objects may be paired with a `VectorIndex` object to create ragged references, so a single cell of a `DynamicTable` can reference many rows of another `DynamicTable`.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"doc":"Reference to the DynamicTable object that this region applies to.","name":"table","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"doc":"Description of what this table region points to.","name":"description","dtype":"text"}]}],"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"Array of unique identifiers for the rows of this dynamic table.","name":"id","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns, including index columns, of this dynamic table.","quantity":"*","data_type_inc":"VectorData"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). These datasets represent different columns in the table. Apart from a column that contains unique identifiers for each row, there are no other required datasets. Users are free to add any number of custom VectorData objects (columns) here. DynamicTable also supports ragged array columns, where each element can be of a different size. To add a ragged array column, use a VectorIndex type to index the corresponding VectorData type. See documentation for VectorData and VectorIndex for more details. Unlike a compound data type, which is analogous to storing an array-of-structs, a DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"doc":"The names of the columns in this table. This should be used to specify an order to the columns.","name":"colnames","dtype":"text","shape":[null],"dims":["num_columns"]},{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text"}]},{"groups":[{"doc":"A DynamicTable representing a particular category for columns in the AlignedDynamicTable parent container. The table MUST be aligned with (i.e., have the same number of rows) as all other DynamicTables stored in the AlignedDynamicTable parent container. The name of the category is given by the name of the DynamicTable and its description by the description attribute of the DynamicTable.","quantity":"*","data_type_inc":"DynamicTable"}],"doc":"DynamicTable container that supports storing a collection of sub-tables. Each sub-table is a DynamicTable itself that is aligned with the main table by row index. I.e., all DynamicTables stored in this group MUST have the same number of rows. This type effectively defines a 2-level table in which the main data is stored in the main table implemented by this type and additional columns of the table are grouped into categories, with each category being represented by a separate DynamicTable stored within the group.","data_type_inc":"DynamicTable","data_type_def":"AlignedDynamicTable","attributes":[{"doc":"The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.","name":"categories","dtype":"text","shape":[null],"dims":["num_categories"]}]}]}(moTREE sHEAPXp0.2.0HprTREExuHEAPX8rexperimentalresourcesnamespace SNOD`ppr8SNODht(ЇvHGCOL {"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The user term that maps to one or more resources in the 'resources' table.","name":"key","dtype":"text"}],"doc":"A table for storing user terms that are used to refer to external resources.","name":"keys","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the key in the 'keys' table.","name":"keys_idx","dtype":"uint"},{"doc":"The index into the 'resources' table","name":"resources_idx","dtype":"uint"},{"doc":"The unique identifier entity.","name":"entity_id","dtype":"text"},{"doc":"The URI for the entity this reference applies to. This can be an empty string.","name":"entity_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"entities","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The name of the resource.","name":"resource","dtype":"text"},{"doc":"The URI for the resource. This can be an empty string.","name":"resource_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"resources","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The UUID for the object.","name":"object_id","dtype":"text"},{"doc":"The relative path from the container with the object_id to the dataset or attribute with the value(s) that is associated with an external resource. This can be an empty string if the container is a dataset which contains the value(s) that is associated with an external resource.","name":"relative_path","dtype":"text"},{"doc":"The field of the compound data type using an external resource. This is used only if the dataset or attribute is a compound data type; otherwise this should be an empty string.","name":"field","dtype":"text"}],"doc":"A table for identifying which objects in a file contain references to external resources.","name":"objects","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the 'objects' table for the object that holds the key.","name":"objects_idx","dtype":"uint"},{"doc":"The index to the 'keys' table for the key.","name":"keys_idx","dtype":"uint"}],"doc":"A table for identifying which objects use which keys.","name":"object_keys","data_type_inc":"Data"}],"doc":"A set of four tables for tracking external resource references in a file. NOTE: this data type is in beta testing and is subject to change in a later version.","data_type_inc":"Container","data_type_def":"ExternalResources"}]}{"namespaces":[{"doc":"Experimental data structures provided by HDMF. These are not guaranteed to be available in the future.","schema":[{"namespace":"hdmf-common"},{"source":"experimental"},{"source":"resources"}],"name":"hdmf-experimental","full_name":"HDMF Experimental","version":"0.2.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Matthew Avaylon"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","mavaylon@lbl.gov"]}]}{"groups":[{"doc":"Metadata about a data acquisition device, e.g., recording system, electrode, microscope.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"doc":"Description of the device (e.g., model, firmware version, processing software version, etc.) as free-form text.","name":"description","required":false,"dtype":"text"},{"doc":"The name of the manufacturer of the device.","name":"manufacturer","required":false,"dtype":"text"}]}]}X(TREE`HEAPXH2.5.0HȋTREEx0HEAP`й0SNODȋhSNODhxGCOL"Y"{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch","name":"count","dtype":"int32"},{"doc":"The TimeSeries that this index applies to","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"doc":"Column storing references to a TimeSeries (rows). For each TimeSeries this VectorData column stores the start_index and count to indicate the range in time to be selected as well as an object reference to the TimeSeries.","default_name":"timeseries","neurodata_type_inc":"VectorData","neurodata_type_def":"TimeSeriesReferenceVectorData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["x","y"],["x","y","r, g, b"],["x","y","r, g, b, a"]],"dtype":"numeric","doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"doc":"Pixel resolution of the image, in pixels per centimeter.","name":"resolution","required":false,"dtype":"float32"},{"doc":"Description of the image.","name":"description","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_images"],"dtype":{"target_type":"Image","reftype":"object"},"doc":"Ordered dataset of references to Image objects.","neurodata_type_inc":"NWBData","neurodata_type_def":"ImageReferences"}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","name":"sync","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float64","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","name":"starting_time","quantity":"?","attributes":[{"doc":"Sampling rate, in Hz.","name":"rate","dtype":"float32"},{"doc":"Unit of measurement for time, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","name":"timestamps","quantity":"?","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","name":"control","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","name":"control_description","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"doc":"Description of the time series.","name":"description","required":false,"dtype":"text","default_value":"no description"},{"doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","name":"comments","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"doc":"Description of this collection of processed data.","name":"description","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"},{"doc":"Ordered dataset of references to Image objects stored in the parent group. Each Image object in the Images group should be stored once and only once, so the dataset should have the same length as the number of images.","name":"order_of_images","quantity":"?","neurodata_type_inc":"ImageReferences"}],"doc":"A collection of images with an optional way to specify the order of the images using the \"order_of_images\" dataset. An order must be specified if the images are referenced by index, e.g., from an IndexSeries.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"doc":"Description of this collection of images.","name":"description","dtype":"text"}]}]}xHEAPX0.1.0Hhdmf-commonhdmf-experimentalcorendx-testextension`GCOL>/{"datasets":[{"shape":[null,null],"dims":["x","y"],"dtype":"numeric","doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage"},{"shape":[null,null,3],"dims":["x","y","r, g, b"],"dtype":"numeric","doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage"},{"shape":[null,null,4],"dims":["x","y","r, g, b, a"],"dtype":"numeric","doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage"}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","x","y"],["frame","x","y","z"]],"dtype":"numeric","doc":"Binary data representing images across frames. If data are stored in an external file, this should be an empty 3D array.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","doc":"Number of pixels on x, y, (and z) axes.","name":"dimension","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","name":"external_file","quantity":"?","attributes":[{"doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","name":"starting_frame","dtype":"int32","shape":[null],"dims":["num_files"]}]},{"dtype":"text","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","name":"format","quantity":"?","default_value":"raw"}],"links":[{"doc":"Link to the Device object that was used to capture these images.","name":"device","target_type":"Device","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][x][y] or [frame][x][y][z].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries"},{"links":[{"doc":"Link to ImageSeries object that this image mask is applied to.","name":"masked_imageseries","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries"},{"datasets":[{"dtype":"float32","doc":"Distance from camera/monitor to target/eye.","name":"distance","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"},{"shape":[[null,null,null],[null,null,null,3]],"dims":[["frame","x","y"],["frame","x","y","r, g, b"]],"dtype":"numeric","doc":"Images presented to subject, either grayscale or RGB","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","name":"orientation","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"uint32","doc":"Index of the image (using zero-indexing) in the linked Images object.","name":"data","attributes":[{"doc":"This field is unused by IndexSeries.","name":"conversion","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries.","name":"resolution","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries.","name":"offset","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries and has the value N/A.","name":"unit","dtype":"text","value":"N/A"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to ImageSeries object containing images that are indexed. Use of this link is discouraged and will be deprecated. Link to an Images type instead.","name":"indexed_timeseries","target_type":"ImageSeries","quantity":"?"},{"doc":"Link to Images object containing an ordered set of images that are indexed. The Images object must contain a 'ordered_images' dataset specifying the order of the images in the Images type.","name":"indexed_images","target_type":"Images","quantity":"?"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the IndexSeries is to allow a static image stack to be stored in an Images object, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced Images object, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries"}]}J{"datasets":[{"doc":"Any one-off datasets","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"doc":"Any notes the user has about the dataset being stored","name":"notes","dtype":"text"}]}],"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.","name":"acquisition"},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.","name":"analysis"},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"ScratchData"}],"doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","name":"scratch","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.","name":"processing"},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Stimuli presented during the experiment.","name":"presentation"},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"},{"doc":"Images objects containing images of presented stimuli.","quantity":"*","neurodata_type_inc":"Images"}],"doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.","name":"templates"}],"doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file.","name":"stimulus"},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"LabMetaData"},{"groups":[{"doc":"Data acquisition devices.","quantity":"*","neurodata_type_inc":"Device"}],"doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","name":"devices","quantity":"?"},{"doc":"Information about the animal or person from which the data was measured.","name":"subject","quantity":"?","neurodata_type_inc":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float32","doc":"x coordinate of the channel location in the brain (+x is posterior).","name":"x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate of the channel location in the brain (+y is inferior).","name":"y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate of the channel location in the brain (+z is right).","name":"z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Impedance of the channel, in ohms.","name":"imp","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of hardware filtering, including the filter name and frequency cutoffs.","name":"filtering","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Reference to the ElectrodeGroup this electrode is a part of.","name":"group","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Name of the ElectrodeGroup this electrode is a part of.","name":"group_name","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"x coordinate in electrode group","name":"rel_x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate in electrode group","name":"rel_y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate in electrode group","name":"rel_z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of the reference electrode and/or reference scheme used for this electrode, e.g., \"stainless steel skull screw\" or \"online common average referencing\".","name":"reference","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"A table of all electrodes (i.e. channels) used for recording.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTable"}],"doc":"Metadata related to extracellular electrophysiology.","name":"extracellular_ephys","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"doc":"[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tabels. Additional SequentialRecordingsTable, RepetitionsTable and ExperimentalConditions tables provide enhanced support for experiment metadata.","name":"sweep_table","quantity":"?","neurodata_type_inc":"SweepTable"},{"doc":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response are recorded as as part of an experiment. In this case both, the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used.","name":"intracellular_recordings","quantity":"?","neurodata_type_inc":"IntracellularRecordingsTable"},{"doc":"A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes","name":"simultaneous_recordings","quantity":"?","neurodata_type_inc":"SimultaneousRecordingsTable"},{"doc":"A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where the a sequence of stimuli of the same type with varying parameters have been presented in a sequence.","name":"sequential_recordings","quantity":"?","neurodata_type_inc":"SequentialRecordingsTable"},{"doc":"A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence.","name":"repetitions","quantity":"?","neurodata_type_inc":"RepetitionsTable"},{"doc":"A table for grouping different intracellular recording repetitions together that belong to the same experimental experimental_conditions.","name":"experimental_conditions","quantity":"?","neurodata_type_inc":"ExperimentalConditionsTable"}],"datasets":[{"dtype":"text","doc":"[DEPRECATED] Use IntracellularElectrode.filtering instead. Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","name":"filtering","quantity":"?"}],"doc":"Metadata related to intracellular electrophysiology.","name":"intracellular_ephys","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"doc":"Metadata describing optogenetic stimuluation.","name":"optogenetics","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"doc":"Metadata related to optophysiology.","name":"optophysiology","quantity":"?"}],"datasets":[{"dtype":"text","doc":"Notes about data collection and analysis.","name":"data_collection","quantity":"?"},{"dtype":"text","doc":"General description of the experiment.","name":"experiment_description","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","name":"experimenter","quantity":"?"},{"dtype":"text","doc":"Institution(s) where experiment was performed.","name":"institution","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","doc":"Terms to search over.","name":"keywords","quantity":"?"},{"dtype":"text","doc":"Laboratory where experiment was performed.","name":"lab","quantity":"?"},{"dtype":"text","doc":"Notes about the experiment.","name":"notes","quantity":"?"},{"dtype":"text","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","name":"pharmacology","quantity":"?"},{"dtype":"text","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","name":"protocol","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","doc":"Publication information. PMID, DOI, URL, etc.","name":"related_publications","quantity":"?"},{"dtype":"text","doc":"Lab-specific ID for the session.","name":"session_id","quantity":"?"},{"dtype":"text","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","name":"slices","quantity":"?"},{"dtype":"text","doc":"Script file or link to public source code used to create this NWB file.","name":"source_script","quantity":"?","attributes":[{"doc":"Name of script file.","name":"file_name","dtype":"text"}]},{"dtype":"text","doc":"Notes about stimuli, such as how and where they were presented.","name":"stimulus","quantity":"?"},{"dtype":"text","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","name":"surgery","quantity":"?"},{"dtype":"text","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","name":"virus","quantity":"?"}],"doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them.","name":"general"},{"groups":[{"doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","name":"epochs","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Repeated experimental events that have a logical grouping.","name":"trials","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Time intervals that should be removed from analysis.","name":"invalid_times","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","name":"intervals","quantity":"?"},{"doc":"Data about sorted spike units.","name":"units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array.","name":"file_create_date"},{"dtype":"text","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files.","name":"identifier"},{"dtype":"text","doc":"A description of the experimental session and data in the file.","name":"session_description"},{"dtype":"isodatetime","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds.","name":"session_start_time"},{"dtype":"isodatetime","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).","name":"timestamps_reference_time"}],"doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","name":"root","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","name":"nwb_version","dtype":"text","value":"2.5.0"}]},{"doc":"Lab-specific meta-data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"datasets":[{"dtype":"text","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","name":"age","quantity":"?"},{"dtype":"isodatetime","doc":"Date of birth of subject. Can be supplied instead of 'age'.","name":"date_of_birth","quantity":"?"},{"dtype":"text","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","name":"description","quantity":"?"},{"dtype":"text","doc":"Genetic strain. If absent, assume Wild Type (WT).","name":"genotype","quantity":"?"},{"dtype":"text","doc":"Gender of subject.","name":"sex","quantity":"?"},{"dtype":"text","doc":"Species of subject.","name":"species","quantity":"?"},{"dtype":"text","doc":"Strain of subject.","name":"strain","quantity":"?"},{"dtype":"text","doc":"ID of animal/person used/participating in experiment (lab convention).","name":"subject_id","quantity":"?"},{"dtype":"text","doc":"Weight at time of experiment, at time of surgery and at other important times.","name":"weight","quantity":"?"}],"doc":"Information about the animal or person from which the data was measured.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"}]}~H{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"Values of each feature at each time.","name":"data","attributes":[{"doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","name":"unit","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Units of each feature.","name":"feature_units","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of the features represented in TimeSeries::data.","name":"features"}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","doc":"Annotations made during an experiment.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","doc":"Use values >0 if interval started, <0 if interval ended.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries"},{"groups":[{"datasets":[{"dtype":"text","doc":"Name of the band, e.g. theta.","name":"band_name","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float32","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","name":"band_limits","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The mean Gaussian filters, in Hz.","name":"band_mean","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The standard deviation of Gaussian filters, in Hz.","name":"band_stdev","neurodata_type_inc":"VectorData"}],"doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","name":"bands","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","doc":"Data decomposed into frequency bands.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"no unit"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"The metric used, e.g. phase, amplitude, power.","name":"metric"},{"doc":"DynamicTableRegion pointer to the channels that this decomposition series was generated from.","name":"source_channels","quantity":"?","neurodata_type_inc":"DynamicTableRegion"}],"links":[{"doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","name":"source_timeseries","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries"},{"datasets":[{"doc":"Index into the spike_times dataset.","name":"spike_times_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"float64","doc":"Spike times for each unit.","name":"spike_times","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"The smallest possible difference between two spike times. Usually 1 divided by the acquisition sampling rate from which spike times were extracted, but could be larger if the acquisition time series was downsampled or smaller if the acquisition time series was smoothed/interpolated and it is possible for the spike time to be between samples.","name":"resolution","required":false,"dtype":"float64"}]},{"doc":"Index into the obs_intervals dataset.","name":"obs_intervals_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"float64","doc":"Observation intervals for each unit.","name":"obs_intervals","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into electrodes.","name":"electrodes_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Electrode group that each spike unit came from.","name":"electrode_group","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform mean for each spike unit.","name":"waveform_mean","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform standard deviation for each spike unit.","name":"waveform_sd","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[null,null],"dims":["num_waveforms","num_samples"],"dtype":"numeric","doc":"Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.","name":"waveforms","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"doc":"Index into the waveforms dataset. One value for every spike event. See 'waveforms' for more detail.","name":"waveforms_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Index into the waveforms_index dataset. One value for every unit (row in the table). See 'waveforms' for more detail.","name":"waveforms_index_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units"}]}f{"groups":[{"datasets":[{"shape":[[null],[null,1],[null,2],[null,3]],"dims":[["num_times"],["num_times","x"],["num_times","x,y"],["num_times","x,y,z"]],"dtype":"numeric","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","required":false,"dtype":"text","default_value":"meters"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description defining what exactly 'straight-ahead' means.","name":"reference_frame","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries"},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]} {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Applied power for optogenetic stimulus, in watts.","name":"data","attributes":[{"doc":"Unit of measurement for data, which is fixed to 'watts'.","name":"unit","dtype":"text","value":"watts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","name":"site","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries"},{"datasets":[{"dtype":"text","doc":"Description of stimulation site.","name":"description"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"text","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"}],"links":[{"doc":"Device that generated the stimulus.","name":"device","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]}( SNOD(H 8Xxnwb.basenwb.devicenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceGCOL<{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","doc":"Recorded voltage data.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion', followed by 'channel_conversion' (if present), and then add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float32","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","name":"channel_conversion","quantity":"?","attributes":[{"doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","name":"axis","dtype":"int32","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"doc":"Filtering applied to all channels of the data. For example, if this ElectricalSeries represents high-pass-filtered data (also known as AP Band), then this value could be \"High-pass 4-pole Bessel filter at 500 Hz\". If this ElectricalSeries represents low-pass-filtered LFP data and the type of filter is unknown, then this value could be \"Low-pass filter at 300 Hz\". If a non-standard filter type is used, provide as much detail about the filter properties as possible.","name":"filtering","required":false,"dtype":"text"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","doc":"Spike waveforms.","name":"data","attributes":[{"doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","name":"timestamps","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries"},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of features (eg, ''PC1'') for each of the extracted features.","name":"description"},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","doc":"Multi-dimensional array of features extracted from each event.","name":"features"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of events that features correspond to (can be a link).","name":"times"},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values.","name":"detection_method"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data.","name":"source_idx"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Timestamps of events, in seconds.","name":"times","attributes":[{"doc":"Unit of measurement for event times, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"links":[{"doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","name":"source_electricalseries","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"datasets":[{"dtype":[{"doc":"x coordinate","name":"x","dtype":"float32"},{"doc":"y coordinate","name":"y","dtype":"float32"},{"doc":"z coordinate","name":"z","dtype":"float32"}],"doc":"stereotaxic or common framework coordinates","name":"position","quantity":"?"}],"links":[{"doc":"Link to the device that was used to record from this electrode group.","name":"device","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"doc":"Description of this electrode group.","name":"description","dtype":"text"},{"doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, etc. Use standard atlas names for anatomical regions when possible.","name":"location","dtype":"text"}]},{"datasets":[{"dtype":"text","doc":"Filtering applied to data before generating mean/sd","name":"waveform_filtering"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)","name":"waveform_mean"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"Stdev of waveforms for each cluster, using the same indices as in mean","name":"waveform_sd"}],"links":[{"doc":"Link to Clustering interface that was the source of the clustered data","name":"clustering_interface","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)","name":"description"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Cluster number of each event","name":"num"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric).","name":"peak_over_rms"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module.","name":"times"}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}f{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Recorded voltage or current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","name":"gain","quantity":"?"}],"links":[{"doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","name":"electrode","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"doc":"Protocol/stimulus name for this patch-clamp dataset.","name":"stimulus_description","dtype":"text"},{"doc":"Sweep number, allows to group different PatchClampSeries together.","name":"sweep_number","required":false,"dtype":"uint32"}]},{"datasets":[{"doc":"Recorded voltage.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Bias current, in amps.","name":"bias_current","quantity":"?"},{"dtype":"float32","doc":"Bridge balance, in ohms.","name":"bridge_balance","quantity":"?"},{"dtype":"float32","doc":"Capacitance compensation, in farads.","name":"capacitance_compensation","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries"},{"datasets":[{"dtype":"float32","doc":"Bias current, in amps, fixed to 0.0.","name":"bias_current"},{"dtype":"float32","doc":"Bridge balance, in ohms, fixed to 0.0.","name":"bridge_balance"},{"dtype":"float32","doc":"Capacitance compensation, in farads, fixed to 0.0.","name":"capacitance_compensation"}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"doc":"An IZeroClampSeries has no stimulus, so this attribute is automatically set to \"N/A\"","name":"stimulus_description","dtype":"text","value":"N/A"}]},{"datasets":[{"doc":"Stimulus current applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries"},{"datasets":[{"doc":"Recorded current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Fast capacitance, in farads.","name":"capacitance_fast","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Slow capacitance, in farads.","name":"capacitance_slow","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Resistance compensation bandwidth, in hertz.","name":"resistance_comp_bandwidth","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","name":"unit","dtype":"text","value":"hertz"}]},{"dtype":"float32","doc":"Resistance compensation correction, in percent.","name":"resistance_comp_correction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Resistance compensation prediction, in percent.","name":"resistance_comp_prediction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Whole cell capacitance compensation, in farads.","name":"whole_cell_capacitance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Whole cell series resistance compensation, in ohms.","name":"whole_cell_series_resistance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","name":"unit","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries"},{"datasets":[{"doc":"Stimulus voltage applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries"},{"datasets":[{"dtype":"text","doc":"unique ID of the cell","name":"cell_id","quantity":"?"},{"dtype":"text","doc":"Description of electrode (e.g., whole-cell, sharp, etc.).","name":"description"},{"dtype":"text","doc":"Electrode specific filtering.","name":"filtering","quantity":"?"},{"dtype":"text","doc":"Initial access resistance.","name":"initial_access_resistance","quantity":"?"},{"dtype":"text","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","quantity":"?"},{"dtype":"text","doc":"Electrode resistance, in ohms.","name":"resistance","quantity":"?"},{"dtype":"text","doc":"Information about seal used for recording.","name":"seal","quantity":"?"},{"dtype":"text","doc":"Information about slice used for recording.","name":"slice","quantity":"?"}],"links":[{"doc":"Device that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint32","doc":"Sweep number of the PatchClampSeries in that row.","name":"sweep_number","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"doc":"The PatchClampSeries with the sweep number in that row.","name":"series","neurodata_type_inc":"VectorData"},{"doc":"Index for series.","name":"series_index","neurodata_type_inc":"VectorIndex"}],"doc":"[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tables. Additional SequentialRecordingsTable, RepetitionsTable, and ExperimentalConditions tables provide enhanced support for experiment metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable"},{"datasets":[{"dtype":{"target_type":"IntracellularElectrode","reftype":"object"},"doc":"Column for storing the reference to the intracellular electrode.","name":"electrode","neurodata_type_inc":"VectorData"}],"doc":"Table for storing intracellular electrode related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularElectrodesTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular electrode related metadata."}]},{"datasets":[{"doc":"Column storing the reference to the recorded stimulus for the recording (rows).","name":"stimulus","neurodata_type_inc":"TimeSeriesReferenceVectorData"}],"doc":"Table for storing intracellular stimulus related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularStimuliTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular stimulus related metadata."}]},{"datasets":[{"doc":"Column storing the reference to the recorded response for the recording (rows)","name":"response","neurodata_type_inc":"TimeSeriesReferenceVectorData"}],"doc":"Table for storing intracellular response related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularResponsesTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular response related metadata."}]},{"groups":[{"doc":"Table for storing intracellular electrode related metadata.","name":"electrodes","neurodata_type_inc":"IntracellularElectrodesTable"},{"doc":"Table for storing intracellular stimulus related metadata.","name":"stimuli","neurodata_type_inc":"IntracellularStimuliTable"},{"doc":"Table for storing intracellular response related metadata.","name":"responses","neurodata_type_inc":"IntracellularResponsesTable"}],"doc":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response is recorded as part of an experiment. In this case, both the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used.","name":"intracellular_recordings","neurodata_type_inc":"AlignedDynamicTable","neurodata_type_def":"IntracellularRecordingsTable","attributes":[{"doc":"Description of the contents of this table. Inherited from AlignedDynamicTable and overwritten here to fix the value of the attribute.","name":"description","dtype":"text","value":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording and for storing metadata about the intracellular recording."}]},{"datasets":[{"doc":"A reference to one or more rows in the IntracellularRecordingsTable table.","name":"recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the IntracellularRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"IntracellularRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the recordings column.","name":"recordings_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes.","name":"simultaneous_recordings","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SimultaneousRecordingsTable"},{"datasets":[{"doc":"A reference to one or more rows in the SimultaneousRecordingsTable table.","name":"simultaneous_recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the SimultaneousRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"SimultaneousRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the simultaneous_recordings column.","name":"simultaneous_recordings_index","neurodata_type_inc":"VectorIndex"},{"dtype":"text","doc":"The type of stimulus used for the sequential recording.","name":"stimulus_type","neurodata_type_inc":"VectorData"}],"doc":"A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where a sequence of stimuli of the same type with varying parameters have been presented in a sequence.","name":"sequential_recordings","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SequentialRecordingsTable"},{"datasets":[{"doc":"A reference to one or more rows in the SequentialRecordingsTable table.","name":"sequential_recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the SequentialRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"SequentialRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the sequential_recordings column.","name":"sequential_recordings_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence.","name":"repetitions","neurodata_type_inc":"DynamicTable","neurodata_type_def":"RepetitionsTable"},{"datasets":[{"doc":"A reference to one or more rows in the RepetitionsTable table.","name":"repetitions","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the RepetitionsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"RepetitionsTable","reftype":"object"}}]},{"doc":"Index dataset for the repetitions column.","name":"repetitions_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different intracellular recording repetitions together that belong to the same experimental condition.","name":"experimental_conditions","neurodata_type_inc":"DynamicTable","neurodata_type_def":"ExperimentalConditionsTable"}]}GCOL0h3{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"}],"links":[{"doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"doc":"Photomultiplier gain.","name":"pmt_gain","required":false,"dtype":"float32"},{"doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","name":"scan_line_rate","required":false,"dtype":"float32"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","doc":"Signals from ROIs.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","name":"rois","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. The first dimension represents time. The second dimension, if present, represents ROIs.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries"},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"PlaneSegmentation"}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"doc":"Image stacks that the segmentation masks apply to.","name":"reference_images"}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","name":"image_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into pixel_mask.","name":"pixel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float32"}],"doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"pixel_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into voxel_mask.","name":"voxel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint32"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float32"}],"doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"voxel_mask","quantity":"?","neurodata_type_inc":"VectorData"}],"links":[{"doc":"Link to ImagingPlane object from which this data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation"},{"groups":[{"doc":"An optical channel used to record from an imaging plane.","quantity":"+","neurodata_type_inc":"OpticalChannel"}],"datasets":[{"dtype":"text","doc":"Description of the imaging plane.","name":"description","quantity":"?"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"float32","doc":"Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead.","name":"imaging_rate","quantity":"?"},{"dtype":"text","doc":"Calcium indicator.","name":"indicator"},{"dtype":"text","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x, y, z"],["height","width","depth","x, y, z"]],"dtype":"float32","doc":"DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing.","name":"manifold","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Base unit of measurement for working with the data. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma).","name":"origin_coords","quantity":"?","attributes":[{"doc":"Measurement units for origin_coords. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid.","name":"grid_spacing","quantity":"?","attributes":[{"doc":"Measurement units for grid_spacing. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","doc":"Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = \"Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral).\"","name":"reference_frame","quantity":"?"}],"links":[{"doc":"Link to the Device object that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An imaging plane and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"datasets":[{"dtype":"text","doc":"Description or other notes about the channel.","name":"description"},{"dtype":"float32","doc":"Emission wavelength for channel, in nm.","name":"emission_lambda"}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"},{"groups":[{"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"},{"groups":[{"doc":"Image stack with frames shifted to the common coordinates.","name":"corrected","neurodata_type_inc":"ImageSeries"},{"doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","name":"xy_translation","neurodata_type_inc":"TimeSeries"}],"links":[{"doc":"Link to ImageSeries object that is being registered.","name":"original","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}]}x{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the first measured axis.","name":"axis_1_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_1_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the second measured axis.","name":"axis_2_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_2_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[2],"dims":["axis_1, axis_2"],"dtype":"text","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta'].","name":"axis_descriptions"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","name":"focal_depth_image","quantity":"?","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Focal depth offset, in meters.","name":"focal_depth","dtype":"float32"},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","name":"sign_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","name":"vasculature_image","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. This group does not store the raw responses imaged during retinotopic mapping or the stimuli presented, but rather the resulting phase and power maps after applying a Fourier transform on the averaged responses. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.device"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.5.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}{"groups":[{"doc":"An extension of TimeSeries to include an ID.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"TimeSeriesWithID","attributes":[{"doc":"The time series ID.","name":"id","dtype":"int32"}]}]}{"namespaces":[{"doc":"An NWB test extension","schema":[{"namespace":"core"},{"source":"ndx-testextension.extensions"}],"name":"ndx-testextension","version":"0.1.0","author":"PyNWB Test File Generator","contact":"my_email@example.com"}]}(TREETREEHEAPX8Pndx-testextension.extensionsnamespace SNOD008SNOD(HH././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/2.2.0_subject_no_age__reference.nwb0000644000175100001730000054256014467767506024300 0ustar00runnerdockerHDF  p` P7hTREEHHAHEAP`?2XDxFHhTREEHEAPXPSNOD Hh(Pp P3H0XxPp TREEHEAPX P 0 TREEHEAPXP P TREE(HEAPX(presentationtemplates0TREEHEAPXPSNODhpTREEHEAPXPXxTREE8HEAPXsubjectHC H namespace 0 .speclocTREE HEAPX0agedescriptionsubject_id(SNODSNOD/ 0GCOLP90DA ratRAT123coreSubject$d8cdab12-2841-410c-aa8c-c91c8ac7cbe4 2022-12-06T00:44:41.747807-08:00ADDME ADDME 2022-12-06T00:44:41.747342-08:00 2022-12-06T00:44:41.747342-08:00 2.5.0 coreNWBFile$0ec52c2e-3fc8-4885-906f-4ef46f149068q{"datasets":[{"doc":"An abstract data type for a dataset.","data_type_def":"Data"}],"groups":[{"doc":"An abstract data type for a group storing collections of data and metadata. Base type for all data and metadata containers.","data_type_def":"Container"},{"groups":[{"doc":"Container objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Container"}],"datasets":[{"doc":"Data objects held within this SimpleMultiContainer.","quantity":"*","data_type_inc":"Data"}],"doc":"A simple Container for holding onto multiple containers.","data_type_inc":"Container","data_type_def":"SimpleMultiContainer"}]}N{"groups":[{"datasets":[{"shape":[null],"dims":["number of non-zero values"],"dtype":"uint","doc":"The column indices.","name":"indices"},{"shape":[null],"dims":["number of rows in the matrix + 1"],"dtype":"uint","doc":"The row index pointer.","name":"indptr"},{"shape":[null],"dims":["number of non-zero values"],"doc":"The non-zero values in the matrix.","name":"data"}],"doc":"A compressed sparse row matrix. Data are stored in the standard CSR format, where column indices for row i are stored in indices[indptr[i]:indptr[i+1]] and their corresponding values are stored in data[indptr[i]:indptr[i+1]].","data_type_inc":"Container","data_type_def":"CSRMatrix","attributes":[{"doc":"The shape (number of rows, number of columns) of this sparse matrix.","name":"shape","dtype":"uint","shape":[2],"dims":["number of rows, number of columns"]}]}]}Z{"namespaces":[{"doc":"Common data structures provided by HDMF","schema":[{"source":"base"},{"source":"table"},{"source":"sparse"}],"name":"hdmf-common","full_name":"HDMF Common","version":"1.5.1","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov"]}]}{"datasets":[{"dtype":"uint8","doc":"Data that come from a fixed set of values. A data value of i corresponds to the i-th value in the VectorData referenced by the 'elements' attribute.","data_type_inc":"VectorData","data_type_def":"EnumData","attributes":[{"doc":"Reference to the VectorData object that contains the enumerable elements","name":"elements","dtype":{"target_type":"VectorData","reftype":"object"}}]}]}{"groups":[{"datasets":[{"dtype":"float32","doc":"Start time of epoch, in seconds.","name":"start_time","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Stop time of epoch, in seconds.","name":"stop_time","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"User-defined tags that identify or categorize events.","name":"tags","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index for tags.","name":"tags_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"An index into a TimeSeries object.","name":"timeseries","quantity":"?","neurodata_type_inc":"TimeSeriesReferenceVectorData"},{"doc":"Index for timeseries.","name":"timeseries_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"A container for aggregating epoch data and the TimeSeries that each epoch applies to.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"TimeIntervals"}]}X77 H namespace Hneurodata_type H object_id$88(888 H nwb_version FI    q@RNZ PwPwY"Pw>/J~Hf<f 30\x0\0\acquisitionanalysisprocessingstimulusgeneralfile_create_dateidentifiersession_descriptionsession_start_timetimestamps_reference_timespecificationsSNODh 4(  0 x05@6XDxF8  BH8 Hneurodata_type H object_id$TREEIHEAPX8Fhdmf-commonhdmf-experimentalcore TREEMHEAPX0I1.5.1HSNOD0`7FI mHmhoJMTREEOHEAPX08Mbasetablesparsenamespace(SNODJJMX8SNODN lk0Qh8GCOL{"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["dim0"],["dim0","dim1"],["dim0","dim1","dim2"],["dim0","dim1","dim2","dim3"]],"doc":"An n-dimensional dataset representing a column of a DynamicTable. If used without an accompanying VectorIndex, first dimension is along the rows of the DynamicTable and each step along the first dimension is a cell of the larger table. VectorData can also be used to represent a ragged array if paired with a VectorIndex. This allows for storing arrays of varying length in a single cell of the DynamicTable by indexing into this VectorData. The first vector is at VectorData[0:VectorIndex[0]]. The second vector is at VectorData[VectorIndex[0]:VectorIndex[1]], and so on.","data_type_inc":"Data","data_type_def":"VectorData","attributes":[{"doc":"Description of what these vectors represent.","name":"description","dtype":"text"}]},{"shape":[null],"dims":["num_rows"],"dtype":"uint8","doc":"Used with VectorData to encode a ragged array. An array of indices into the first dimension of the target VectorData, and forming a map between the rows of a DynamicTable and the indices of the VectorData. The name of the VectorIndex is expected to be the name of the target VectorData object followed by \"_index\".","data_type_inc":"VectorData","data_type_def":"VectorIndex","attributes":[{"doc":"Reference to the target dataset that this index applies to.","name":"target","dtype":{"target_type":"VectorData","reftype":"object"}}]},{"shape":[null],"dims":["num_elements"],"dtype":"int","doc":"A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.","default_name":"element_id","data_type_inc":"Data","data_type_def":"ElementIdentifiers"},{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"DynamicTableRegion provides a link from one table to an index or region of another. The `table` attribute is a link to another `DynamicTable`, indicating which table is referenced, and the data is int(s) indicating the row(s) (0-indexed) of the target array. `DynamicTableRegion`s can be used to associate rows with repeated meta-data without data duplication. They can also be used to create hierarchical relationships between multiple `DynamicTable`s. `DynamicTableRegion` objects may be paired with a `VectorIndex` object to create ragged references, so a single cell of a `DynamicTable` can reference many rows of another `DynamicTable`.","data_type_inc":"VectorData","data_type_def":"DynamicTableRegion","attributes":[{"doc":"Reference to the DynamicTable object that this region applies to.","name":"table","dtype":{"target_type":"DynamicTable","reftype":"object"}},{"doc":"Description of what this table region points to.","name":"description","dtype":"text"}]}],"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":"int","doc":"Array of unique identifiers for the rows of this dynamic table.","name":"id","data_type_inc":"ElementIdentifiers"},{"doc":"Vector columns, including index columns, of this dynamic table.","quantity":"*","data_type_inc":"VectorData"}],"doc":"A group containing multiple datasets that are aligned on the first dimension (Currently, this requirement if left up to APIs to check and enforce). These datasets represent different columns in the table. Apart from a column that contains unique identifiers for each row, there are no other required datasets. Users are free to add any number of custom VectorData objects (columns) here. DynamicTable also supports ragged array columns, where each element can be of a different size. To add a ragged array column, use a VectorIndex type to index the corresponding VectorData type. See documentation for VectorData and VectorIndex for more details. Unlike a compound data type, which is analogous to storing an array-of-structs, a DynamicTable can be thought of as a struct-of-arrays. This provides an alternative structure to choose from when optimizing storage for anticipated access patterns. Additionally, this type provides a way of creating a table without having to define a compound type up front. Although this convenience may be attractive, users should think carefully about how data will be accessed. DynamicTable is more appropriate for column-centric access, whereas a dataset with a compound type would be more appropriate for row-centric access. Finally, data size should also be taken into account. For small tables, performance loss may be an acceptable trade-off for the flexibility of a DynamicTable.","data_type_inc":"Container","data_type_def":"DynamicTable","attributes":[{"doc":"The names of the columns in this table. This should be used to specify an order to the columns.","name":"colnames","dtype":"text","shape":[null],"dims":["num_columns"]},{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text"}]},{"groups":[{"doc":"A DynamicTable representing a particular category for columns in the AlignedDynamicTable parent container. The table MUST be aligned with (i.e., have the same number of rows) as all other DynamicTables stored in the AlignedDynamicTable parent container. The name of the category is given by the name of the DynamicTable and its description by the description attribute of the DynamicTable.","quantity":"*","data_type_inc":"DynamicTable"}],"doc":"DynamicTable container that supports storing a collection of sub-tables. Each sub-table is a DynamicTable itself that is aligned with the main table by row index. I.e., all DynamicTables stored in this group MUST have the same number of rows. This type effectively defines a 2-level table in which the main data is stored in the main table implemented by this type and additional columns of the table are grouped into categories, with each category being represented by a separate DynamicTable stored within the group.","data_type_inc":"DynamicTable","data_type_def":"AlignedDynamicTable","attributes":[{"doc":"The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.","name":"categories","dtype":"text","shape":[null],"dims":["num_categories"]}]}]}x88HmhoTREErHEAPXo0.2.0Hp(rTREEtHEAPX8Hrexperimentalresourcesnamespace SNODop(r8SNODs(P@v8GCOL {"groups":[{"datasets":[{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The user term that maps to one or more resources in the 'resources' table.","name":"key","dtype":"text"}],"doc":"A table for storing user terms that are used to refer to external resources.","name":"keys","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the key in the 'keys' table.","name":"keys_idx","dtype":"uint"},{"doc":"The index into the 'resources' table","name":"resources_idx","dtype":"uint"},{"doc":"The unique identifier entity.","name":"entity_id","dtype":"text"},{"doc":"The URI for the entity this reference applies to. This can be an empty string.","name":"entity_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"entities","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The name of the resource.","name":"resource","dtype":"text"},{"doc":"The URI for the resource. This can be an empty string.","name":"resource_uri","dtype":"text"}],"doc":"A table for mapping user terms (i.e., keys) to resource entities.","name":"resources","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The UUID for the object.","name":"object_id","dtype":"text"},{"doc":"The relative path from the container with the object_id to the dataset or attribute with the value(s) that is associated with an external resource. This can be an empty string if the container is a dataset which contains the value(s) that is associated with an external resource.","name":"relative_path","dtype":"text"},{"doc":"The field of the compound data type using an external resource. This is used only if the dataset or attribute is a compound data type; otherwise this should be an empty string.","name":"field","dtype":"text"}],"doc":"A table for identifying which objects in a file contain references to external resources.","name":"objects","data_type_inc":"Data"},{"shape":[null],"dims":["num_rows"],"dtype":[{"doc":"The index to the 'objects' table for the object that holds the key.","name":"objects_idx","dtype":"uint"},{"doc":"The index to the 'keys' table for the key.","name":"keys_idx","dtype":"uint"}],"doc":"A table for identifying which objects use which keys.","name":"object_keys","data_type_inc":"Data"}],"doc":"A set of four tables for tracking external resource references in a file. NOTE: this data type is in beta testing and is subject to change in a later version.","data_type_inc":"Container","data_type_def":"ExternalResources"}]}{"namespaces":[{"doc":"Experimental data structures provided by HDMF. These are not guaranteed to be available in the future.","schema":[{"namespace":"hdmf-common"},{"source":"experimental"},{"source":"resources"}],"name":"hdmf-experimental","full_name":"HDMF Experimental","version":"0.2.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Matthew Avaylon"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","mavaylon@lbl.gov"]}]}{"groups":[{"doc":"Metadata about a data acquisition device, e.g., recording system, electrode, microscope.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Device","attributes":[{"doc":"Description of the device (e.g., model, firmware version, processing software version, etc.) as free-form text.","name":"description","required":false,"dtype":"text"},{"doc":"The name of the manufacturer of the device.","name":"manufacturer","required":false,"dtype":"text"}]}]}8TREEHEAPXȊ2.5.0HHhTREE8xHEAP`SNOD Hh8SNOD`(hxGCOL"Y"{"datasets":[{"doc":"An abstract data type for a dataset.","neurodata_type_inc":"Data","neurodata_type_def":"NWBData"},{"dtype":[{"doc":"Start index into the TimeSeries 'data' and 'timestamp' datasets of the referenced TimeSeries. The first dimension of those arrays is always time.","name":"idx_start","dtype":"int32"},{"doc":"Number of data samples available in this time series, during this epoch","name":"count","dtype":"int32"},{"doc":"The TimeSeries that this index applies to","name":"timeseries","dtype":{"target_type":"TimeSeries","reftype":"object"}}],"doc":"Column storing references to a TimeSeries (rows). For each TimeSeries this VectorData column stores the start_index and count to indicate the range in time to be selected as well as an object reference to the TimeSeries.","default_name":"timeseries","neurodata_type_inc":"VectorData","neurodata_type_def":"TimeSeriesReferenceVectorData"},{"shape":[[null,null],[null,null,3],[null,null,4]],"dims":[["x","y"],["x","y","r, g, b"],["x","y","r, g, b, a"]],"dtype":"numeric","doc":"An abstract data type for an image. Shape can be 2-D (x, y), or 3-D where the third dimension can have three or four elements, e.g. (x, y, (r, g, b)) or (x, y, (r, g, b, a)).","neurodata_type_inc":"NWBData","neurodata_type_def":"Image","attributes":[{"doc":"Pixel resolution of the image, in pixels per centimeter.","name":"resolution","required":false,"dtype":"float32"},{"doc":"Description of the image.","name":"description","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_images"],"dtype":{"target_type":"Image","reftype":"object"},"doc":"Ordered dataset of references to Image objects.","neurodata_type_inc":"NWBData","neurodata_type_def":"ImageReferences"}],"groups":[{"doc":"An abstract data type for a generic container storing collections of data and metadata. Base type for all data and metadata containers.","neurodata_type_inc":"Container","neurodata_type_def":"NWBContainer"},{"doc":"An abstract data type for a generic container storing collections of data, as opposed to metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBDataInterface"},{"groups":[{"doc":"Lab-specific time and sync information as provided directly from hardware devices and that is necessary for aligning all acquired time information to a common timebase. The timestamp array stores time in the common timebase. This group will usually only be populated in TimeSeries that are stored external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes.","name":"sync","quantity":"?"}],"datasets":[{"shape":[[null],[null,null],[null,null,null],[null,null,null,null]],"dims":[["num_times"],["num_times","num_DIM2"],["num_times","num_DIM2","num_DIM3"],["num_times","num_DIM2","num_DIM3","num_DIM4"]],"doc":"Data values. Data can be in 1-D, 2-D, 3-D, or 4-D. The first dimension should always represent time. This can also be used to store binary data (e.g., image frames). This can also be a link to data stored in an external file.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float64","doc":"Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute.","name":"starting_time","quantity":"?","attributes":[{"doc":"Sampling rate, in Hz.","name":"rate","dtype":"float32"},{"doc":"Unit of measurement for time, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time.","name":"timestamps","quantity":"?","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]},{"shape":[null],"dims":["num_times"],"dtype":"uint8","doc":"Numerical labels that apply to each time point in data for the purpose of querying and slicing data by these values. If present, the length of this array should be the same size as the first dimension of data.","name":"control","quantity":"?"},{"shape":[null],"dims":["num_control_values"],"dtype":"text","doc":"Description of each control value. Must be present if control is present. If present, control_description[0] should describe time points where control == 0.","name":"control_description","quantity":"?"}],"doc":"General purpose time series.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"TimeSeries","attributes":[{"doc":"Description of the time series.","name":"description","required":false,"dtype":"text","default_value":"no description"},{"doc":"Human-readable comments about the TimeSeries. This second descriptive field can be used to store additional information, or descriptive information if the primary description field is populated with a computer-readable string.","name":"comments","required":false,"dtype":"text","default_value":"no comments"}]},{"groups":[{"doc":"Data objects stored in this collection.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tables stored in this collection.","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"A collection of processed data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ProcessingModule","attributes":[{"doc":"Description of this collection of processed data.","name":"description","dtype":"text"}]},{"datasets":[{"doc":"Images stored in this collection.","quantity":"+","neurodata_type_inc":"Image"},{"doc":"Ordered dataset of references to Image objects stored in the parent group. Each Image object in the Images group should be stored once and only once, so the dataset should have the same length as the number of images.","name":"order_of_images","quantity":"?","neurodata_type_inc":"ImageReferences"}],"doc":"A collection of images with an optional way to specify the order of the images using the \"order_of_images\" dataset. An order must be specified if the images are referenced by index, e.g., from an IndexSeries.","default_name":"Images","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Images","attributes":[{"doc":"Description of this collection of images.","name":"description","dtype":"text"}]}]}88899(9GCOL>/{"datasets":[{"shape":[null,null],"dims":["x","y"],"dtype":"numeric","doc":"A grayscale image.","neurodata_type_inc":"Image","neurodata_type_def":"GrayscaleImage"},{"shape":[null,null,3],"dims":["x","y","r, g, b"],"dtype":"numeric","doc":"A color image.","neurodata_type_inc":"Image","neurodata_type_def":"RGBImage"},{"shape":[null,null,4],"dims":["x","y","r, g, b, a"],"dtype":"numeric","doc":"A color image with transparency.","neurodata_type_inc":"Image","neurodata_type_def":"RGBAImage"}],"groups":[{"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["frame","x","y"],["frame","x","y","z"]],"dtype":"numeric","doc":"Binary data representing images across frames. If data are stored in an external file, this should be an empty 3D array.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["rank"],"dtype":"int32","doc":"Number of pixels on x, y, (and z) axes.","name":"dimension","quantity":"?"},{"shape":[null],"dims":["num_files"],"dtype":"text","doc":"Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.","name":"external_file","quantity":"?","attributes":[{"doc":"Each external image may contain one or more consecutive frames of the full ImageSeries. This attribute serves as an index to indicate which frames each file contains, to faciliate random access. The 'starting_frame' attribute, hence, contains a list of frame numbers within the full ImageSeries of the first frame of each file listed in the parent 'external_file' dataset. Zero-based indexing is used (hence, the first element will always be zero). For example, if the 'external_file' dataset has three paths to files and the first file has 5 frames, the second file has 10 frames, and the third file has 20 frames, then this attribute will have values [0, 5, 15]. If there is a single external file that holds all of the frames of the ImageSeries (and so there is a single element in the 'external_file' dataset), then this attribute should have value [0].","name":"starting_frame","dtype":"int32","shape":[null],"dims":["num_files"]}]},{"dtype":"text","doc":"Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.","name":"format","quantity":"?","default_value":"raw"}],"links":[{"doc":"Link to the Device object that was used to capture these images.","name":"device","target_type":"Device","quantity":"?"}],"doc":"General image data that is common between acquisition and stimulus time series. Sometimes the image data is stored in the file in a raw format while other times it will be stored as a series of external image files in the host file system. The data field will either be binary data, if the data is stored in the NWB file, or empty, if the data is stored in an external image stack. [frame][x][y] or [frame][x][y][z].","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ImageSeries"},{"links":[{"doc":"Link to ImageSeries object that this image mask is applied to.","name":"masked_imageseries","target_type":"ImageSeries"}],"doc":"An alpha mask that is applied to a presented visual stimulus. The 'data' array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask pattern continues until it's explicitly changed.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"ImageMaskSeries"},{"datasets":[{"dtype":"float32","doc":"Distance from camera/monitor to target/eye.","name":"distance","quantity":"?"},{"shape":[[2],[3]],"dims":[["width, height"],["width, height, depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"},{"shape":[[null,null,null],[null,null,null,3]],"dims":[["frame","x","y"],["frame","x","y","r, g, b"]],"dtype":"numeric","doc":"Images presented to subject, either grayscale or RGB","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.","name":"orientation","quantity":"?"}],"doc":"Image data that is presented or recorded. A stimulus template movie will be stored only as an image. When the image is presented as stimulus, additional data is required, such as field of view (e.g., how much of the visual field the image covers, or how what is the area of the target being imaged). If the OpticalSeries represents acquired imaging data, orientation is also important.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"OpticalSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"uint32","doc":"Index of the image (using zero-indexing) in the linked Images object.","name":"data","attributes":[{"doc":"This field is unused by IndexSeries.","name":"conversion","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries.","name":"resolution","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries.","name":"offset","required":false,"dtype":"float32"},{"doc":"This field is unused by IndexSeries and has the value N/A.","name":"unit","dtype":"text","value":"N/A"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to ImageSeries object containing images that are indexed. Use of this link is discouraged and will be deprecated. Link to an Images type instead.","name":"indexed_timeseries","target_type":"ImageSeries","quantity":"?"},{"doc":"Link to Images object containing an ordered set of images that are indexed. The Images object must contain a 'ordered_images' dataset specifying the order of the images in the Images type.","name":"indexed_images","target_type":"Images","quantity":"?"}],"doc":"Stores indices to image frames stored in an ImageSeries. The purpose of the IndexSeries is to allow a static image stack to be stored in an Images object, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced Images object, and the timestamps array indicates when that image was displayed.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IndexSeries"}]}J{"datasets":[{"doc":"Any one-off datasets","neurodata_type_inc":"NWBData","neurodata_type_def":"ScratchData","attributes":[{"doc":"Any notes the user has about the dataset being stored","name":"notes","dtype":"text"}]}],"groups":[{"groups":[{"groups":[{"doc":"Acquired, raw data.","quantity":"*","neurodata_type_inc":"NWBDataInterface"},{"doc":"Tabular data that is relevent to acquisition","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.","name":"acquisition"},{"groups":[{"doc":"Custom analysis results.","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Tabular data that is relevent to data stored in analysis","quantity":"*","neurodata_type_inc":"DynamicTable"}],"doc":"Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.","name":"analysis"},{"groups":[{"doc":"Any one-off containers","quantity":"*","neurodata_type_inc":"NWBContainer"},{"doc":"Any one-off tables","quantity":"*","neurodata_type_inc":"DynamicTable"}],"datasets":[{"doc":"Any one-off datasets","quantity":"*","neurodata_type_inc":"ScratchData"}],"doc":"A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.","name":"scratch","quantity":"?"},{"groups":[{"doc":"Intermediate analysis of acquired data.","quantity":"*","neurodata_type_inc":"ProcessingModule"}],"doc":"The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.","name":"processing"},{"groups":[{"groups":[{"doc":"TimeSeries objects containing data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"Stimuli presented during the experiment.","name":"presentation"},{"groups":[{"doc":"TimeSeries objects containing template data of presented stimuli.","quantity":"*","neurodata_type_inc":"TimeSeries"},{"doc":"Images objects containing images of presented stimuli.","quantity":"*","neurodata_type_inc":"Images"}],"doc":"Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.","name":"templates"}],"doc":"Data pushed into the system (eg, video stimulus, sound, voltage, etc) and secondary representations of that data (eg, measurements of something used as a stimulus). This group should be made read-only after experiment complete and timestamps are corrected to common timebase. Stores both presented stimuli and stimulus templates, the latter in case the same stimulus is presented multiple times, or is pulled from an external stimulus library. Stimuli are here defined as any signal that is pushed into the system as part of the experiment (eg, sound, video, voltage, etc). Many different experiments can use the same stimuli, and stimuli can be re-used during an experiment. The stimulus group is organized so that one version of template stimuli can be stored and these be used multiple times. These templates can exist in the present file or can be linked to a remote library file.","name":"stimulus"},{"groups":[{"doc":"Place-holder than can be extended so that lab-specific meta-data can be placed in /general.","quantity":"*","neurodata_type_inc":"LabMetaData"},{"groups":[{"doc":"Data acquisition devices.","quantity":"*","neurodata_type_inc":"Device"}],"doc":"Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.","name":"devices","quantity":"?"},{"doc":"Information about the animal or person from which the data was measured.","name":"subject","quantity":"?","neurodata_type_inc":"Subject"},{"groups":[{"doc":"Physical group of electrodes.","quantity":"*","neurodata_type_inc":"ElectrodeGroup"},{"datasets":[{"dtype":"float32","doc":"x coordinate of the channel location in the brain (+x is posterior).","name":"x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate of the channel location in the brain (+y is inferior).","name":"y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate of the channel location in the brain (+z is right).","name":"z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"Impedance of the channel, in ohms.","name":"imp","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Location of the electrode (channel). Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of hardware filtering, including the filter name and frequency cutoffs.","name":"filtering","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Reference to the ElectrodeGroup this electrode is a part of.","name":"group","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Name of the ElectrodeGroup this electrode is a part of.","name":"group_name","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"x coordinate in electrode group","name":"rel_x","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"y coordinate in electrode group","name":"rel_y","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"float32","doc":"z coordinate in electrode group","name":"rel_z","quantity":"?","neurodata_type_inc":"VectorData"},{"dtype":"text","doc":"Description of the reference electrode and/or reference scheme used for this electrode, e.g., \"stainless steel skull screw\" or \"online common average referencing\".","name":"reference","quantity":"?","neurodata_type_inc":"VectorData"}],"doc":"A table of all electrodes (i.e. channels) used for recording.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTable"}],"doc":"Metadata related to extracellular electrophysiology.","name":"extracellular_ephys","quantity":"?"},{"groups":[{"doc":"An intracellular electrode.","quantity":"*","neurodata_type_inc":"IntracellularElectrode"},{"doc":"[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tabels. Additional SequentialRecordingsTable, RepetitionsTable and ExperimentalConditions tables provide enhanced support for experiment metadata.","name":"sweep_table","quantity":"?","neurodata_type_inc":"SweepTable"},{"doc":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response are recorded as as part of an experiment. In this case both, the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used.","name":"intracellular_recordings","quantity":"?","neurodata_type_inc":"IntracellularRecordingsTable"},{"doc":"A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes","name":"simultaneous_recordings","quantity":"?","neurodata_type_inc":"SimultaneousRecordingsTable"},{"doc":"A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where the a sequence of stimuli of the same type with varying parameters have been presented in a sequence.","name":"sequential_recordings","quantity":"?","neurodata_type_inc":"SequentialRecordingsTable"},{"doc":"A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence.","name":"repetitions","quantity":"?","neurodata_type_inc":"RepetitionsTable"},{"doc":"A table for grouping different intracellular recording repetitions together that belong to the same experimental experimental_conditions.","name":"experimental_conditions","quantity":"?","neurodata_type_inc":"ExperimentalConditionsTable"}],"datasets":[{"dtype":"text","doc":"[DEPRECATED] Use IntracellularElectrode.filtering instead. Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.","name":"filtering","quantity":"?"}],"doc":"Metadata related to intracellular electrophysiology.","name":"intracellular_ephys","quantity":"?"},{"groups":[{"doc":"An optogenetic stimulation site.","quantity":"*","neurodata_type_inc":"OptogeneticStimulusSite"}],"doc":"Metadata describing optogenetic stimuluation.","name":"optogenetics","quantity":"?"},{"groups":[{"doc":"An imaging plane.","quantity":"*","neurodata_type_inc":"ImagingPlane"}],"doc":"Metadata related to optophysiology.","name":"optophysiology","quantity":"?"}],"datasets":[{"dtype":"text","doc":"Notes about data collection and analysis.","name":"data_collection","quantity":"?"},{"dtype":"text","doc":"General description of the experiment.","name":"experiment_description","quantity":"?"},{"shape":[null],"dims":["num_experimenters"],"dtype":"text","doc":"Name of person(s) who performed the experiment. Can also specify roles of different people involved.","name":"experimenter","quantity":"?"},{"dtype":"text","doc":"Institution(s) where experiment was performed.","name":"institution","quantity":"?"},{"shape":[null],"dims":["num_keywords"],"dtype":"text","doc":"Terms to search over.","name":"keywords","quantity":"?"},{"dtype":"text","doc":"Laboratory where experiment was performed.","name":"lab","quantity":"?"},{"dtype":"text","doc":"Notes about the experiment.","name":"notes","quantity":"?"},{"dtype":"text","doc":"Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.","name":"pharmacology","quantity":"?"},{"dtype":"text","doc":"Experimental protocol, if applicable. e.g., include IACUC protocol number.","name":"protocol","quantity":"?"},{"shape":[null],"dims":["num_publications"],"dtype":"text","doc":"Publication information. PMID, DOI, URL, etc.","name":"related_publications","quantity":"?"},{"dtype":"text","doc":"Lab-specific ID for the session.","name":"session_id","quantity":"?"},{"dtype":"text","doc":"Description of slices, including information about preparation thickness, orientation, temperature, and bath solution.","name":"slices","quantity":"?"},{"dtype":"text","doc":"Script file or link to public source code used to create this NWB file.","name":"source_script","quantity":"?","attributes":[{"doc":"Name of script file.","name":"file_name","dtype":"text"}]},{"dtype":"text","doc":"Notes about stimuli, such as how and where they were presented.","name":"stimulus","quantity":"?"},{"dtype":"text","doc":"Narrative description about surgery/surgeries, including date(s) and who performed surgery.","name":"surgery","quantity":"?"},{"dtype":"text","doc":"Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.","name":"virus","quantity":"?"}],"doc":"Experimental metadata, including protocol, notes and description of hardware device(s). The metadata stored in this section should be used to describe the experiment. Metadata necessary for interpreting the data is stored with the data. General experimental metadata, including animal strain, experimental protocols, experimenter, devices, etc, are stored under 'general'. Core metadata (e.g., that required to interpret data fields) is stored with the data itself, and implicitly defined by the file specification (e.g., time is in seconds). The strategy used here for storing non-core metadata is to use free-form text fields, such as would appear in sentences or paragraphs from a Methods section. Metadata fields are text to enable them to be more general, for example to represent ranges instead of numerical values. Machine-readable metadata is stored as attributes to these free-form datasets. All entries in the below table are to be included when data is present. Unused groups (e.g., intracellular_ephys in an optophysiology experiment) should not be created unless there is data to store within them.","name":"general"},{"groups":[{"doc":"Divisions in time marking experimental stages or sub-divisions of a single recording session.","name":"epochs","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Repeated experimental events that have a logical grouping.","name":"trials","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Time intervals that should be removed from analysis.","name":"invalid_times","quantity":"?","neurodata_type_inc":"TimeIntervals"},{"doc":"Optional additional table(s) for describing other experimental time intervals.","quantity":"*","neurodata_type_inc":"TimeIntervals"}],"doc":"Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.","name":"intervals","quantity":"?"},{"doc":"Data about sorted spike units.","name":"units","quantity":"?","neurodata_type_inc":"Units"}],"datasets":[{"shape":[null],"dims":["num_modifications"],"dtype":"isodatetime","doc":"A record of the date the file was created and of subsequent modifications. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted strings: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. The file can be created after the experiment was run, so this may differ from the experiment start time. Each modification to the nwb file adds a new entry to the array.","name":"file_create_date"},{"dtype":"text","doc":"A unique text identifier for the file. For example, concatenated lab name, file creation date/time and experimentalist, or a hash of these and/or other values. The goal is that the string should be unique to all other files.","name":"identifier"},{"dtype":"text","doc":"A description of the experimental session and data in the file.","name":"session_description"},{"dtype":"isodatetime","doc":"Date and time of the experiment/session start. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds.","name":"session_start_time"},{"dtype":"isodatetime","doc":"Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).","name":"timestamps_reference_time"}],"doc":"An NWB:N file storing cellular-based neurophysiology data from a single experimental session.","name":"root","neurodata_type_inc":"NWBContainer","neurodata_type_def":"NWBFile","attributes":[{"doc":"File version string. Use semantic versioning, e.g. 1.2.1. This will be the name of the format with trailing major, minor and patch numbers.","name":"nwb_version","dtype":"text","value":"2.5.0"}]},{"doc":"Lab-specific meta-data.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"LabMetaData"},{"datasets":[{"dtype":"text","doc":"Age of subject. Can be supplied instead of 'date_of_birth'.","name":"age","quantity":"?"},{"dtype":"isodatetime","doc":"Date of birth of subject. Can be supplied instead of 'age'.","name":"date_of_birth","quantity":"?"},{"dtype":"text","doc":"Description of subject and where subject came from (e.g., breeder, if animal).","name":"description","quantity":"?"},{"dtype":"text","doc":"Genetic strain. If absent, assume Wild Type (WT).","name":"genotype","quantity":"?"},{"dtype":"text","doc":"Gender of subject.","name":"sex","quantity":"?"},{"dtype":"text","doc":"Species of subject.","name":"species","quantity":"?"},{"dtype":"text","doc":"Strain of subject.","name":"strain","quantity":"?"},{"dtype":"text","doc":"ID of animal/person used/participating in experiment (lab convention).","name":"subject_id","quantity":"?"},{"dtype":"text","doc":"Weight at time of experiment, at time of surgery and at other important times.","name":"weight","quantity":"?"}],"doc":"Information about the animal or person from which the data was measured.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"Subject"}]}~H{"groups":[{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_features"]],"dtype":"numeric","doc":"Values of each feature at each time.","name":"data","attributes":[{"doc":"Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".","name":"unit","required":false,"dtype":"text","default_value":"see 'feature_units'"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Units of each feature.","name":"feature_units","quantity":"?"},{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of the features represented in TimeSeries::data.","name":"features"}],"doc":"Abstract features, such as quantitative descriptions of sensory stimuli. The TimeSeries::data field is a 2D array, storing those features (e.g., for visual grating stimulus this might be orientation, spatial frequency and contrast). Null stimuli (eg, uniform gray) can be marked as being an independent feature (eg, 1.0 for gray, 0.0 for actual stimulus) or by storing NaNs for feature values, or through use of the TimeSeries::control fields. A set of features is considered to persist until the next set of features is defined. The final set of features stored should be the null set. This is useful when storing the raw stimulus is impractical.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AbstractFeatureSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"text","doc":"Annotations made during an experiment.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores user annotations made during an experiment. The data[] field stores a text array, and timestamps are stored for each annotation (ie, interval=1). This is largely an alias to a standard TimeSeries storing a text array but that is identifiable as storing annotations in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"AnnotationSeries"},{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"int8","doc":"Use values >0 if interval started, <0 if interval ended.","name":"data","attributes":[{"doc":"Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.","name":"resolution","dtype":"float32","value":-1.0},{"doc":"Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.","name":"unit","dtype":"text","value":"n/a"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"IntervalSeries"},{"groups":[{"datasets":[{"dtype":"text","doc":"Name of the band, e.g. theta.","name":"band_name","neurodata_type_inc":"VectorData"},{"shape":[null,2],"dims":["num_bands","low, high"],"dtype":"float32","doc":"Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.","name":"band_limits","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The mean Gaussian filters, in Hz.","name":"band_mean","neurodata_type_inc":"VectorData"},{"shape":[null],"dims":["num_bands"],"dtype":"float32","doc":"The standard deviation of Gaussian filters, in Hz.","name":"band_stdev","neurodata_type_inc":"VectorData"}],"doc":"Table for describing the bands that this series was generated from. There should be one row in this table for each band.","name":"bands","neurodata_type_inc":"DynamicTable"}],"datasets":[{"shape":[null,null,null],"dims":["num_times","num_channels","num_bands"],"dtype":"numeric","doc":"Data decomposed into frequency bands.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.","name":"unit","required":false,"dtype":"text","default_value":"no unit"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"The metric used, e.g. phase, amplitude, power.","name":"metric"},{"doc":"DynamicTableRegion pointer to the channels that this decomposition series was generated from.","name":"source_channels","quantity":"?","neurodata_type_inc":"DynamicTableRegion"}],"links":[{"doc":"Link to TimeSeries object that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it is not necessary to store that information here.","name":"source_timeseries","target_type":"TimeSeries","quantity":"?"}],"doc":"Spectral analysis of a time series, e.g. of an LFP or a speech signal.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"DecompositionSeries"},{"datasets":[{"doc":"Index into the spike_times dataset.","name":"spike_times_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":"float64","doc":"Spike times for each unit.","name":"spike_times","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"The smallest possible difference between two spike times. Usually 1 divided by the acquisition sampling rate from which spike times were extracted, but could be larger if the acquisition time series was downsampled or smaller if the acquisition time series was smoothed/interpolated and it is possible for the spike time to be between samples.","name":"resolution","required":false,"dtype":"float64"}]},{"doc":"Index into the obs_intervals dataset.","name":"obs_intervals_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"shape":[null,2],"dims":["num_intervals","start|end"],"dtype":"float64","doc":"Observation intervals for each unit.","name":"obs_intervals","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into electrodes.","name":"electrodes_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Electrode that each spike unit came from, specified using a DynamicTableRegion.","name":"electrodes","quantity":"?","neurodata_type_inc":"DynamicTableRegion"},{"dtype":{"target_type":"ElectrodeGroup","reftype":"object"},"doc":"Electrode group that each spike unit came from.","name":"electrode_group","quantity":"?","neurodata_type_inc":"VectorData"},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform mean for each spike unit.","name":"waveform_mean","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[[null,null],[null,null,null]],"dims":[["num_units","num_samples"],["num_units","num_samples","num_electrodes"]],"dtype":"float32","doc":"Spike waveform standard deviation for each spike unit.","name":"waveform_sd","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"shape":[null,null],"dims":["num_waveforms","num_samples"],"dtype":"numeric","doc":"Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.","name":"waveforms","quantity":"?","neurodata_type_inc":"VectorData","attributes":[{"doc":"Sampling rate, in hertz.","name":"sampling_rate","required":false,"dtype":"float32"},{"doc":"Unit of measurement. This value is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"}]},{"doc":"Index into the waveforms dataset. One value for every spike event. See 'waveforms' for more detail.","name":"waveforms_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"doc":"Index into the waveforms_index dataset. One value for every unit (row in the table). See 'waveforms' for more detail.","name":"waveforms_index_index","quantity":"?","neurodata_type_inc":"VectorIndex"}],"doc":"Data about spiking units. Event times of observed units (e.g. cell, synapse, etc.) should be concatenated and stored in spike_times.","default_name":"Units","neurodata_type_inc":"DynamicTable","neurodata_type_def":"Units"}]}f{"groups":[{"datasets":[{"shape":[[null],[null,1],[null,2],[null,3]],"dims":[["num_times"],["num_times","x"],["num_times","x,y"],["num_times","x,y,z"]],"dtype":"numeric","doc":"1-D or 2-D array storing position or direction relative to some reference frame.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","required":false,"dtype":"text","default_value":"meters"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"text","doc":"Description defining what exactly 'straight-ahead' means.","name":"reference_frame","quantity":"?"}],"doc":"Direction, e.g., of gaze or travel, or position. The TimeSeries::data field is a 2D array storing position or direction relative to some reference frame. Array structure: [num measurements] [num dimensions]. Each SpatialSeries has a text dataset reference_frame that indicates the zero-position, or the zero-axes for direction. For example, if representing gaze direction, 'straight-ahead' might be a specific pixel on the monitor, or some other point in space. For position data, the 0,0 point might be the top-left corner of an enclosure, as viewed from the tracking camera. The unit of data will indicate how to interpret SpatialSeries values.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"SpatialSeries"},{"groups":[{"doc":"IntervalSeries object containing start and stop times of epochs.","quantity":"*","neurodata_type_inc":"IntervalSeries"}],"doc":"TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data.","default_name":"BehavioralEpochs","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEpochs"},{"groups":[{"doc":"TimeSeries object containing behavioral events.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details.","default_name":"BehavioralEvents","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralEvents"},{"groups":[{"doc":"TimeSeries object containing continuous behavioral data.","quantity":"*","neurodata_type_inc":"TimeSeries"}],"doc":"TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details.","default_name":"BehavioralTimeSeries","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"BehavioralTimeSeries"},{"groups":[{"doc":"TimeSeries object containing time series data on pupil size.","quantity":"+","neurodata_type_inc":"TimeSeries"}],"doc":"Eye-tracking data, representing pupil size.","default_name":"PupilTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"PupilTracking"},{"groups":[{"doc":"SpatialSeries object containing data measuring direction of gaze.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"Eye-tracking data, representing direction of gaze.","default_name":"EyeTracking","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EyeTracking"},{"groups":[{"doc":"SpatialSeries object containing direction of gaze travel.","quantity":"*","neurodata_type_inc":"SpatialSeries"}],"doc":"With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees.","default_name":"CompassDirection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CompassDirection"},{"groups":[{"doc":"SpatialSeries object containing position data.","quantity":"+","neurodata_type_inc":"SpatialSeries"}],"doc":"Position data, whether along the x, x/y or x/y/z axis.","default_name":"Position","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Position"}]} {"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Applied power for optogenetic stimulus, in watts.","name":"data","attributes":[{"doc":"Unit of measurement for data, which is fixed to 'watts'.","name":"unit","dtype":"text","value":"watts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"links":[{"doc":"Link to OptogeneticStimulusSite object that describes the site to which this stimulus was applied.","name":"site","target_type":"OptogeneticStimulusSite"}],"doc":"An optogenetic stimulus.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"OptogeneticSeries"},{"datasets":[{"dtype":"text","doc":"Description of stimulation site.","name":"description"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"text","doc":"Location of the stimulation site. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"}],"links":[{"doc":"Device that generated the stimulus.","name":"device","target_type":"Device"}],"doc":"A site of optogenetic stimulation.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OptogeneticStimulusSite"}]}( 89H9SNOD(H08 X@hxX9nwb.basenwb.devicenwb.epochnwb.imagenwb.filenwb.miscnwb.behaviornwb.ecephysnwb.icephysnwb.ogennwb.ophysnwb.retinotopynamespaceh9x9GCOL<{"groups":[{"datasets":[{"shape":[[null],[null,null],[null,null,null]],"dims":[["num_times"],["num_times","num_channels"],["num_times","num_channels","num_samples"]],"dtype":"numeric","doc":"Recorded voltage data.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion', followed by 'channel_conversion' (if present), and then add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"},{"shape":[null],"dims":["num_channels"],"dtype":"float32","doc":"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.","name":"channel_conversion","quantity":"?","attributes":[{"doc":"The zero-indexed axis of the 'data' dataset that the channel-specific conversion factor corresponds to. This value is fixed to 1.","name":"axis","dtype":"int32","value":1}]}],"doc":"A time series of acquired voltage data from extracellular recordings. The data field is an int or float array storing data in volts. The first dimension should always represent time. The second dimension, if present, should represent channels.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"ElectricalSeries","attributes":[{"doc":"Filtering applied to all channels of the data. For example, if this ElectricalSeries represents high-pass-filtered data (also known as AP Band), then this value could be \"High-pass 4-pole Bessel filter at 500 Hz\". If this ElectricalSeries represents low-pass-filtered LFP data and the type of filter is unknown, then this value could be \"Low-pass filter at 300 Hz\". If a non-standard filter type is used, provide as much detail about the filter properties as possible.","name":"filtering","required":false,"dtype":"text"}]},{"datasets":[{"shape":[[null,null],[null,null,null]],"dims":[["num_events","num_samples"],["num_events","num_channels","num_samples"]],"dtype":"numeric","doc":"Spike waveforms.","name":"data","attributes":[{"doc":"Unit of measurement for waveforms, which is fixed to 'volts'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"shape":[null],"dims":["num_times"],"dtype":"float64","doc":"Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.","name":"timestamps","attributes":[{"doc":"Value is '1'","name":"interval","dtype":"int32","value":1},{"doc":"Unit of measurement for timestamps, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"doc":"Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode).","neurodata_type_inc":"ElectricalSeries","neurodata_type_def":"SpikeEventSeries"},{"datasets":[{"shape":[null],"dims":["num_features"],"dtype":"text","doc":"Description of features (eg, ''PC1'') for each of the extracted features.","name":"description"},{"shape":[null,null,null],"dims":["num_events","num_channels","num_features"],"dtype":"float32","doc":"Multi-dimensional array of features extracted from each event.","name":"features"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of events that features correspond to (can be a link).","name":"times"},{"doc":"DynamicTableRegion pointer to the electrodes that this time series was generated from.","name":"electrodes","neurodata_type_inc":"DynamicTableRegion"}],"doc":"Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source.","default_name":"FeatureExtraction","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FeatureExtraction"},{"datasets":[{"dtype":"text","doc":"Description of how events were detected, such as voltage threshold, or dV/dT threshold, as well as relevant values.","name":"detection_method"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Indices (zero-based) into source ElectricalSeries::data array corresponding to time of event. ''description'' should define what is meant by time of event (e.g., .25 ms before action potential peak, zero-crossing time, etc). The index points to each event from the raw data.","name":"source_idx"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Timestamps of events, in seconds.","name":"times","attributes":[{"doc":"Unit of measurement for event times, which is fixed to 'seconds'.","name":"unit","dtype":"text","value":"seconds"}]}],"links":[{"doc":"Link to the ElectricalSeries that this data was calculated from. Metadata about electrodes and their position can be read from that ElectricalSeries so it's not necessary to include that information here.","name":"source_electricalseries","target_type":"ElectricalSeries"}],"doc":"Detected spike events from voltage trace(s).","default_name":"EventDetection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventDetection"},{"groups":[{"doc":"SpikeEventSeries object(s) containing detected spike event waveforms.","quantity":"*","neurodata_type_inc":"SpikeEventSeries"}],"doc":"Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition.","default_name":"EventWaveform","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"EventWaveform"},{"groups":[{"doc":"ElectricalSeries object(s) containing filtered electrophysiology data.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"FilteredEphys","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"FilteredEphys"},{"groups":[{"doc":"ElectricalSeries object(s) containing LFP data for one or more channels.","quantity":"+","neurodata_type_inc":"ElectricalSeries"}],"doc":"LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries 'filtering' attribute.","default_name":"LFP","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"LFP"},{"datasets":[{"dtype":[{"doc":"x coordinate","name":"x","dtype":"float32"},{"doc":"y coordinate","name":"y","dtype":"float32"},{"doc":"z coordinate","name":"z","dtype":"float32"}],"doc":"stereotaxic or common framework coordinates","name":"position","quantity":"?"}],"links":[{"doc":"Link to the device that was used to record from this electrode group.","name":"device","target_type":"Device"}],"doc":"A physical grouping of electrodes, e.g. a shank of an array.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ElectrodeGroup","attributes":[{"doc":"Description of this electrode group.","name":"description","dtype":"text"},{"doc":"Location of electrode group. Specify the area, layer, comments on estimation of area/layer, etc. Use standard atlas names for anatomical regions when possible.","name":"location","dtype":"text"}]},{"datasets":[{"dtype":"text","doc":"Filtering applied to data before generating mean/sd","name":"waveform_filtering"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"The mean waveform for each cluster, using the same indices for each wave as cluster numbers in the associated Clustering module (i.e, cluster 3 is in array slot [3]). Waveforms corresponding to gaps in cluster sequence should be empty (e.g., zero- filled)","name":"waveform_mean"},{"shape":[null,null],"dims":["num_clusters","num_samples"],"dtype":"float32","doc":"Stdev of waveforms for each cluster, using the same indices as in mean","name":"waveform_sd"}],"links":[{"doc":"Link to Clustering interface that was the source of the clustered data","name":"clustering_interface","target_type":"Clustering"}],"doc":"DEPRECATED The mean waveform shape, including standard deviation, of the different clusters. Ideally, the waveform analysis should be performed on data that is only high-pass filtered. This is a separate module because it is expected to require updating. For example, IMEC probes may require different storage requirements to store/display mean waveforms, requiring a new interface or an extension of this one.","default_name":"ClusterWaveforms","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ClusterWaveforms"},{"datasets":[{"dtype":"text","doc":"Description of clusters or clustering, (e.g. cluster 0 is noise, clusters curated using Klusters, etc)","name":"description"},{"shape":[null],"dims":["num_events"],"dtype":"int32","doc":"Cluster number of each event","name":"num"},{"shape":[null],"dims":["num_clusters"],"dtype":"float32","doc":"Maximum ratio of waveform peak to RMS on any channel in the cluster (provides a basic clustering metric).","name":"peak_over_rms"},{"shape":[null],"dims":["num_events"],"dtype":"float64","doc":"Times of clustered events, in seconds. This may be a link to times field in associated FeatureExtraction module.","name":"times"}],"doc":"DEPRECATED Clustered spike data, whether from automatic clustering tools (e.g., klustakwik) or as a result of manual sorting.","default_name":"Clustering","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Clustering"}]}f{"groups":[{"datasets":[{"shape":[null],"dims":["num_times"],"dtype":"numeric","doc":"Recorded voltage or current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp).","name":"gain","quantity":"?"}],"links":[{"doc":"Link to IntracellularElectrode object that describes the electrode that was used to apply or record this data.","name":"electrode","target_type":"IntracellularElectrode"}],"doc":"An abstract base class for patch-clamp data - stimulus or response, current or voltage.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"PatchClampSeries","attributes":[{"doc":"Protocol/stimulus name for this patch-clamp dataset.","name":"stimulus_description","dtype":"text"},{"doc":"Sweep number, allows to group different PatchClampSeries together.","name":"sweep_number","required":false,"dtype":"uint32"}]},{"datasets":[{"doc":"Recorded voltage.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Bias current, in amps.","name":"bias_current","quantity":"?"},{"dtype":"float32","doc":"Bridge balance, in ohms.","name":"bridge_balance","quantity":"?"},{"dtype":"float32","doc":"Capacitance compensation, in farads.","name":"capacitance_compensation","quantity":"?"}],"doc":"Voltage data from an intracellular current-clamp recording. A corresponding CurrentClampStimulusSeries (stored separately as a stimulus) is used to store the current injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampSeries"},{"datasets":[{"dtype":"float32","doc":"Bias current, in amps, fixed to 0.0.","name":"bias_current"},{"dtype":"float32","doc":"Bridge balance, in ohms, fixed to 0.0.","name":"bridge_balance"},{"dtype":"float32","doc":"Capacitance compensation, in farads, fixed to 0.0.","name":"capacitance_compensation"}],"doc":"Voltage data from an intracellular recording when all current and amplifier settings are off (i.e., CurrentClampSeries fields will be zero). There is no CurrentClampStimulusSeries associated with an IZero series because the amplifier is disconnected and no stimulus can reach the cell.","neurodata_type_inc":"CurrentClampSeries","neurodata_type_def":"IZeroClampSeries","attributes":[{"doc":"An IZeroClampSeries has no stimulus, so this attribute is automatically set to \"N/A\"","name":"stimulus_description","dtype":"text","value":"N/A"}]},{"datasets":[{"doc":"Stimulus current applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus current applied during current clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"CurrentClampStimulusSeries"},{"datasets":[{"doc":"Recorded current.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"amperes"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"dtype":"float32","doc":"Fast capacitance, in farads.","name":"capacitance_fast","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Slow capacitance, in farads.","name":"capacitance_slow","quantity":"?","attributes":[{"doc":"Unit of measurement for capacitance_fast, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Resistance compensation bandwidth, in hertz.","name":"resistance_comp_bandwidth","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_bandwidth, which is fixed to 'hertz'.","name":"unit","dtype":"text","value":"hertz"}]},{"dtype":"float32","doc":"Resistance compensation correction, in percent.","name":"resistance_comp_correction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_correction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Resistance compensation prediction, in percent.","name":"resistance_comp_prediction","quantity":"?","attributes":[{"doc":"Unit of measurement for resistance_comp_prediction, which is fixed to 'percent'.","name":"unit","dtype":"text","value":"percent"}]},{"dtype":"float32","doc":"Whole cell capacitance compensation, in farads.","name":"whole_cell_capacitance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_capacitance_comp, which is fixed to 'farads'.","name":"unit","dtype":"text","value":"farads"}]},{"dtype":"float32","doc":"Whole cell series resistance compensation, in ohms.","name":"whole_cell_series_resistance_comp","quantity":"?","attributes":[{"doc":"Unit of measurement for whole_cell_series_resistance_comp, which is fixed to 'ohms'.","name":"unit","dtype":"text","value":"ohms"}]}],"doc":"Current data from an intracellular voltage-clamp recording. A corresponding VoltageClampStimulusSeries (stored separately as a stimulus) is used to store the voltage injected.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampSeries"},{"datasets":[{"doc":"Stimulus voltage applied.","name":"data","attributes":[{"doc":"Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text","value":"volts"},{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]}],"doc":"Stimulus voltage applied during a voltage clamp recording.","neurodata_type_inc":"PatchClampSeries","neurodata_type_def":"VoltageClampStimulusSeries"},{"datasets":[{"dtype":"text","doc":"unique ID of the cell","name":"cell_id","quantity":"?"},{"dtype":"text","doc":"Description of electrode (e.g., whole-cell, sharp, etc.).","name":"description"},{"dtype":"text","doc":"Electrode specific filtering.","name":"filtering","quantity":"?"},{"dtype":"text","doc":"Initial access resistance.","name":"initial_access_resistance","quantity":"?"},{"dtype":"text","doc":"Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location","quantity":"?"},{"dtype":"text","doc":"Electrode resistance, in ohms.","name":"resistance","quantity":"?"},{"dtype":"text","doc":"Information about seal used for recording.","name":"seal","quantity":"?"},{"dtype":"text","doc":"Information about slice used for recording.","name":"slice","quantity":"?"}],"links":[{"doc":"Device that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An intracellular electrode and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"IntracellularElectrode"},{"datasets":[{"dtype":"uint32","doc":"Sweep number of the PatchClampSeries in that row.","name":"sweep_number","neurodata_type_inc":"VectorData"},{"dtype":{"target_type":"PatchClampSeries","reftype":"object"},"doc":"The PatchClampSeries with the sweep number in that row.","name":"series","neurodata_type_inc":"VectorData"},{"doc":"Index for series.","name":"series_index","neurodata_type_inc":"VectorIndex"}],"doc":"[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tables. Additional SequentialRecordingsTable, RepetitionsTable, and ExperimentalConditions tables provide enhanced support for experiment metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SweepTable"},{"datasets":[{"dtype":{"target_type":"IntracellularElectrode","reftype":"object"},"doc":"Column for storing the reference to the intracellular electrode.","name":"electrode","neurodata_type_inc":"VectorData"}],"doc":"Table for storing intracellular electrode related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularElectrodesTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular electrode related metadata."}]},{"datasets":[{"doc":"Column storing the reference to the recorded stimulus for the recording (rows).","name":"stimulus","neurodata_type_inc":"TimeSeriesReferenceVectorData"}],"doc":"Table for storing intracellular stimulus related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularStimuliTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular stimulus related metadata."}]},{"datasets":[{"doc":"Column storing the reference to the recorded response for the recording (rows)","name":"response","neurodata_type_inc":"TimeSeriesReferenceVectorData"}],"doc":"Table for storing intracellular response related metadata.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"IntracellularResponsesTable","attributes":[{"doc":"Description of what is in this dynamic table.","name":"description","dtype":"text","value":"Table for storing intracellular response related metadata."}]},{"groups":[{"doc":"Table for storing intracellular electrode related metadata.","name":"electrodes","neurodata_type_inc":"IntracellularElectrodesTable"},{"doc":"Table for storing intracellular stimulus related metadata.","name":"stimuli","neurodata_type_inc":"IntracellularStimuliTable"},{"doc":"Table for storing intracellular response related metadata.","name":"responses","neurodata_type_inc":"IntracellularResponsesTable"}],"doc":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording. Each row in the table represents a single recording consisting typically of a stimulus and a corresponding response. In some cases, however, only a stimulus or a response is recorded as part of an experiment. In this case, both the stimulus and response will point to the same TimeSeries while the idx_start and count of the invalid column will be set to -1, thus, indicating that no values have been recorded for the stimulus or response, respectively. Note, a recording MUST contain at least a stimulus or a response. Typically the stimulus and response are PatchClampSeries. However, the use of AD/DA channels that are not associated to an electrode is also common in intracellular electrophysiology, in which case other TimeSeries may be used.","name":"intracellular_recordings","neurodata_type_inc":"AlignedDynamicTable","neurodata_type_def":"IntracellularRecordingsTable","attributes":[{"doc":"Description of the contents of this table. Inherited from AlignedDynamicTable and overwritten here to fix the value of the attribute.","name":"description","dtype":"text","value":"A table to group together a stimulus and response from a single electrode and a single simultaneous recording and for storing metadata about the intracellular recording."}]},{"datasets":[{"doc":"A reference to one or more rows in the IntracellularRecordingsTable table.","name":"recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the IntracellularRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"IntracellularRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the recordings column.","name":"recordings_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different intracellular recordings from the IntracellularRecordingsTable table together that were recorded simultaneously from different electrodes.","name":"simultaneous_recordings","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SimultaneousRecordingsTable"},{"datasets":[{"doc":"A reference to one or more rows in the SimultaneousRecordingsTable table.","name":"simultaneous_recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the SimultaneousRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"SimultaneousRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the simultaneous_recordings column.","name":"simultaneous_recordings_index","neurodata_type_inc":"VectorIndex"},{"dtype":"text","doc":"The type of stimulus used for the sequential recording.","name":"stimulus_type","neurodata_type_inc":"VectorData"}],"doc":"A table for grouping different sequential recordings from the SimultaneousRecordingsTable table together. This is typically used to group together sequential recordings where a sequence of stimuli of the same type with varying parameters have been presented in a sequence.","name":"sequential_recordings","neurodata_type_inc":"DynamicTable","neurodata_type_def":"SequentialRecordingsTable"},{"datasets":[{"doc":"A reference to one or more rows in the SequentialRecordingsTable table.","name":"sequential_recordings","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the SequentialRecordingsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"SequentialRecordingsTable","reftype":"object"}}]},{"doc":"Index dataset for the sequential_recordings column.","name":"sequential_recordings_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different sequential intracellular recordings together. With each SequentialRecording typically representing a particular type of stimulus, the RepetitionsTable table is typically used to group sets of stimuli applied in sequence.","name":"repetitions","neurodata_type_inc":"DynamicTable","neurodata_type_def":"RepetitionsTable"},{"datasets":[{"doc":"A reference to one or more rows in the RepetitionsTable table.","name":"repetitions","neurodata_type_inc":"DynamicTableRegion","attributes":[{"doc":"Reference to the RepetitionsTable table that this table region applies to. This specializes the attribute inherited from DynamicTableRegion to fix the type of table that can be referenced here.","name":"table","dtype":{"target_type":"RepetitionsTable","reftype":"object"}}]},{"doc":"Index dataset for the repetitions column.","name":"repetitions_index","neurodata_type_inc":"VectorIndex"}],"doc":"A table for grouping different intracellular recording repetitions together that belong to the same experimental condition.","name":"experimental_conditions","neurodata_type_inc":"DynamicTable","neurodata_type_def":"ExperimentalConditionsTable"}]}GCOL0h3{"groups":[{"datasets":[{"shape":[[2],[3]],"dims":[["width|height"],["width|height|depth"]],"dtype":"float32","doc":"Width, height and depth of image, or imaged area, in meters.","name":"field_of_view","quantity":"?"}],"links":[{"doc":"Link to ImagingPlane object from which this TimeSeries data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Image stack recorded over time from 2-photon microscope.","neurodata_type_inc":"ImageSeries","neurodata_type_def":"TwoPhotonSeries","attributes":[{"doc":"Photomultiplier gain.","name":"pmt_gain","required":false,"dtype":"float32"},{"doc":"Lines imaged per second. This is also stored in /general/optophysiology but is kept here as it is useful information for analysis, and so good to be stored w/ the actual data.","name":"scan_line_rate","required":false,"dtype":"float32"}]},{"datasets":[{"shape":[[null],[null,null]],"dims":[["num_times"],["num_times","num_ROIs"]],"dtype":"numeric","doc":"Signals from ROIs.","name":"data","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Scalar to add to the data after scaling by 'conversion' to finalize its coercion to the specified 'unit'. Two common examples of this include (a) data stored in an unsigned type that requires a shift after scaling to re-center the data, and (b) specialized recording devices that naturally cause a scalar offset with respect to the true units.","name":"offset","required":false,"dtype":"float32","default_value":0.0},{"doc":"Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.","name":"resolution","required":false,"dtype":"float32","default_value":-1.0},{"doc":"Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and add 'offset'.","name":"unit","dtype":"text"},{"doc":"Optionally describe the continuity of the data. Can be \"continuous\", \"instantaneous\", or \"step\". For example, a voltage trace would be \"continuous\", because samples are recorded from a continuous process. An array of lick times would be \"instantaneous\", because the data represents distinct moments in time. Times of image presentations would be \"step\" because the picture remains the same until the next timepoint. This field is optional, but is useful in providing information about the underlying data. It may inform the way this data is interpreted, the way it is visualized, and what analysis methods are applicable.","name":"continuity","required":false,"dtype":"text"}]},{"doc":"DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.","name":"rois","neurodata_type_inc":"DynamicTableRegion"}],"doc":"ROI responses over an imaging plane. The first dimension represents time. The second dimension, if present, represents ROIs.","neurodata_type_inc":"TimeSeries","neurodata_type_def":"RoiResponseSeries"},{"groups":[{"doc":"RoiResponseSeries object(s) containing dF/F for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes).","default_name":"DfOverF","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"DfOverF"},{"groups":[{"doc":"RoiResponseSeries object(s) containing fluorescence data for a ROI.","quantity":"+","neurodata_type_inc":"RoiResponseSeries"}],"doc":"Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes).","default_name":"Fluorescence","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"Fluorescence"},{"groups":[{"doc":"Results from image segmentation of a specific imaging plane.","quantity":"+","neurodata_type_inc":"PlaneSegmentation"}],"doc":"Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them.","default_name":"ImageSegmentation","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImageSegmentation"},{"groups":[{"groups":[{"doc":"One or more image stacks that the masks apply to (can be one-element stack).","quantity":"*","neurodata_type_inc":"ImageSeries"}],"doc":"Image stacks that the segmentation masks apply to.","name":"reference_images"}],"datasets":[{"shape":[[null,null,null],[null,null,null,null]],"dims":[["num_roi","num_x","num_y"],["num_roi","num_x","num_y","num_z"]],"doc":"ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.","name":"image_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into pixel_mask.","name":"pixel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Pixel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Pixel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Weight of the pixel.","name":"weight","dtype":"float32"}],"doc":"Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"pixel_mask","quantity":"?","neurodata_type_inc":"VectorData"},{"doc":"Index into voxel_mask.","name":"voxel_mask_index","quantity":"?","neurodata_type_inc":"VectorIndex"},{"dtype":[{"doc":"Voxel x-coordinate.","name":"x","dtype":"uint32"},{"doc":"Voxel y-coordinate.","name":"y","dtype":"uint32"},{"doc":"Voxel z-coordinate.","name":"z","dtype":"uint32"},{"doc":"Weight of the voxel.","name":"weight","dtype":"float32"}],"doc":"Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation","name":"voxel_mask","quantity":"?","neurodata_type_inc":"VectorData"}],"links":[{"doc":"Link to ImagingPlane object from which this data was generated.","name":"imaging_plane","target_type":"ImagingPlane"}],"doc":"Results from image segmentation of a specific imaging plane.","neurodata_type_inc":"DynamicTable","neurodata_type_def":"PlaneSegmentation"},{"groups":[{"doc":"An optical channel used to record from an imaging plane.","quantity":"+","neurodata_type_inc":"OpticalChannel"}],"datasets":[{"dtype":"text","doc":"Description of the imaging plane.","name":"description","quantity":"?"},{"dtype":"float32","doc":"Excitation wavelength, in nm.","name":"excitation_lambda"},{"dtype":"float32","doc":"Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead.","name":"imaging_rate","quantity":"?"},{"dtype":"text","doc":"Calcium indicator.","name":"indicator"},{"dtype":"text","doc":"Location of the imaging plane. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible.","name":"location"},{"shape":[[null,null,3],[null,null,null,3]],"dims":[["height","width","x, y, z"],["height","width","depth","x, y, z"]],"dtype":"float32","doc":"DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing.","name":"manifold","quantity":"?","attributes":[{"doc":"Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as pixels from x = -500 to 499, y = -500 to 499 that correspond to a 2 m x 2 m range, then the 'conversion' multiplier to get from raw data acquisition pixel units to meters is 2/1000.","name":"conversion","required":false,"dtype":"float32","default_value":1.0},{"doc":"Base unit of measurement for working with the data. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma).","name":"origin_coords","quantity":"?","attributes":[{"doc":"Measurement units for origin_coords. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"shape":[[2],[3]],"dims":[["x, y"],["x, y, z"]],"dtype":"float32","doc":"Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid.","name":"grid_spacing","quantity":"?","attributes":[{"doc":"Measurement units for grid_spacing. The default value is 'meters'.","name":"unit","required":false,"dtype":"text","default_value":"meters"}]},{"dtype":"text","doc":"Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = \"Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral).\"","name":"reference_frame","quantity":"?"}],"links":[{"doc":"Link to the Device object that was used to record from this electrode.","name":"device","target_type":"Device"}],"doc":"An imaging plane and its metadata.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"ImagingPlane"},{"datasets":[{"dtype":"text","doc":"Description or other notes about the channel.","name":"description"},{"dtype":"float32","doc":"Emission wavelength for channel, in nm.","name":"emission_lambda"}],"doc":"An optical channel used to record from an imaging plane.","neurodata_type_inc":"NWBContainer","neurodata_type_def":"OpticalChannel"},{"groups":[{"doc":"Reuslts from motion correction of an image stack.","quantity":"+","neurodata_type_inc":"CorrectedImageStack"}],"doc":"An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions).","default_name":"MotionCorrection","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"MotionCorrection"},{"groups":[{"doc":"Image stack with frames shifted to the common coordinates.","name":"corrected","neurodata_type_inc":"ImageSeries"},{"doc":"Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image.","name":"xy_translation","neurodata_type_inc":"TimeSeries"}],"links":[{"doc":"Link to ImageSeries object that is being registered.","name":"original","target_type":"ImageSeries"}],"doc":"Reuslts from motion correction of an image stack.","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"CorrectedImageStack"}]}x{"groups":[{"datasets":[{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the first measured axis.","name":"axis_1_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_1_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Phase response to stimulus on the second measured axis.","name":"axis_2_phase_map","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power.","name":"axis_2_power_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Unit that axis data is stored in (e.g., degrees).","name":"unit","dtype":"text"}]},{"shape":[2],"dims":["axis_1, axis_2"],"dtype":"text","doc":"Two-element array describing the contents of the two response axis fields. Description should be something like ['altitude', 'azimuth'] or '['radius', 'theta'].","name":"axis_descriptions"},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].","name":"focal_depth_image","quantity":"?","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value.","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Focal depth offset, in meters.","name":"focal_depth","dtype":"float32"},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"float32","doc":"Sine of the angle between the direction of the gradient in axis_1 and axis_2.","name":"sign_map","quantity":"?","attributes":[{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]}]},{"shape":[null,null],"dims":["num_rows","num_cols"],"dtype":"uint16","doc":"Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]","name":"vasculature_image","attributes":[{"doc":"Number of bits used to represent each value. This is necessary to determine maximum (white) pixel value","name":"bits_per_pixel","dtype":"int32"},{"doc":"Number of rows and columns in the image. NOTE: row, column representation is equivalent to height, width.","name":"dimension","dtype":"int32","shape":[2],"dims":["num_rows, num_cols"]},{"doc":"Size of viewing area, in meters.","name":"field_of_view","dtype":"float32","shape":[2],"dims":["height, width"]},{"doc":"Format of image. Right now only 'raw' is supported.","name":"format","dtype":"text"}]}],"doc":"Intrinsic signal optical imaging or widefield imaging for measuring retinotopy. Stores orthogonal maps (e.g., altitude/azimuth; radius/theta) of responses to specific stimuli and a combined polarity map from which to identify visual areas. This group does not store the raw responses imaged during retinotopic mapping or the stimuli presented, but rather the resulting phase and power maps after applying a Fourier transform on the averaged responses. Note: for data consistency, all images and arrays are stored in the format [row][column] and [row, col], which equates to [y][x]. Field of view and dimension arrays may appear backward (i.e., y before x).","default_name":"ImagingRetinotopy","neurodata_type_inc":"NWBDataInterface","neurodata_type_def":"ImagingRetinotopy"}]}{"namespaces":[{"doc":"NWB namespace","schema":[{"namespace":"hdmf-common"},{"source":"nwb.base"},{"source":"nwb.device"},{"source":"nwb.epoch"},{"source":"nwb.image"},{"source":"nwb.file"},{"source":"nwb.misc"},{"source":"nwb.behavior"},{"source":"nwb.ecephys"},{"source":"nwb.icephys"},{"source":"nwb.ogen"},{"source":"nwb.ophys"},{"source":"nwb.retinotopy"}],"name":"core","full_name":"NWB core","version":"2.5.0","author":["Andrew Tritt","Oliver Ruebel","Ryan Ly","Ben Dichter","Keith Godfrey","Jeff Teeters"],"contact":["ajtritt@lbl.gov","oruebel@lbl.gov","rly@lbl.gov","bdichter@lbl.gov","keithg@alleninstitute.org","jteeters@berkeley.edu"]}]}9././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/__init__.py0000644000175100001730000000000014467767506020010 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/test_import_structure.py0000644000175100001730000000455214467767506022762 0ustar00runnerdockerfrom unittest import TestCase import pynwb class TestImportStructure(TestCase): """Test whether the classes/modules imported from pynwb in version 2.1.1 are still accessible. NOTE: this test was needed to ensure backward compatibility of "import pynwb" after changes to the package file hierarchy in PyNWB 2.2.0 around validate.py (see https://github.com/NeurodataWithoutBorders/pynwb/pull/1511). """ def test_outer_import_structure(self): current_structure = dir(pynwb) expected_structure = [ "BuildManager", "CORE_NAMESPACE", "DataChunkIterator", "H5DataIO", "HDMFIO", "NWBContainer", "NWBData", "NWBDatasetSpec", "NWBFile", "NWBGroupSpec", "NWBHDF5IO", "NWBNamespace", "NamespaceCatalog", "Path", "ProcessingModule", "TimeSeries", "TypeMap", "_HDF5IO", "__NS_CATALOG", "__TYPE_MAP", "__builtins__", "__cached__", "__doc__", "__file__", "__get_resources", "__io", "__loader__", "__name__", "__package__", "__path__", "__resources", "__spec__", "__version__", "_due", "_get_resources", "_version", "available_namespaces", "base", "behavior", "core", "deepcopy", "device", "docval", "ecephys", "epoch", "file", "get_class", "get_docval", "get_manager", "get_type_map", "getargs", "h5py", "hdmf", "hdmf_typemap", "icephys", "image", "io", "legacy", "load_namespaces", "misc", "ogen", "ophys", "os", "popargs", "register_class", "register_map", "retinotopy", "spec", "testing", "validate", "warn", ] for member in expected_structure: self.assertIn(member=member, container=current_structure) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/back_compat/test_read.py0000644000175100001730000001536114467767506020243 0ustar00runnerdockerimport numpy as np from pathlib import Path import warnings from pynwb import NWBHDF5IO, validate, TimeSeries from pynwb.image import ImageSeries from pynwb.testing import TestCase class TestReadOldVersions(TestCase): expected_warnings = { '' '2.1.0_imageseries_non_external_format.nwb': [( "ImageSeries 'test_imageseries': Format must be 'external' when external_file is specified." )], '2.1.0_imageseries_nonmatch_starting_frame.nwb': [( "ImageSeries 'test_imageseries': The number of frame indices in 'starting_frame' should have the same " "length as 'external_file'." )], } expected_errors = { '1.0.2_str_experimenter.nwb': [("root/general/experimenter (general/experimenter): incorrect shape - expected " "an array of shape '[None]', got non-array data 'one experimenter'")], '1.0.3_str_experimenter.nwb': [("root/general/experimenter (general/experimenter): incorrect shape - expected " "an array of shape '[None]', got non-array data 'one experimenter'")], '1.0.2_str_pub.nwb': [("root/general/related_publications (general/related_publications): incorrect shape " "- expected an array of shape '[None]', got non-array data 'one publication'")], '1.0.3_str_pub.nwb': [("root/general/related_publications (general/related_publications): incorrect shape " "- expected an array of shape '[None]', got non-array data 'one publication'")], } def test_read(self): """Test reading and validating all NWB files in the same folder as this file. This folder contains NWB files generated by previous versions of NWB using the script src/pynwb/testing/make_test_files.py """ dir_path = Path(__file__).parent nwb_files = dir_path.glob('*.nwb') for f in nwb_files: with self.subTest(file=f.name): with warnings.catch_warnings(record=True) as warnings_on_read: warnings.simplefilter("always") with NWBHDF5IO(str(f), 'r', load_namespaces=True) as io: errors = validate(io) io.read() for w in warnings_on_read: if f.name in self.expected_warnings: if str(w.message) not in self.expected_warnings[f.name]: pass # will replace above with below after the test file is updated # raise Exception("Unexpected warning: %s: %s" % (f.name, str(w.message))) else: pass # will replace above with below after the test file is updated # raise Exception("Unexpected warning: %s: %s" % (f.name, str(w.message))) if errors: for e in errors: if f.name in self.expected_errors: if str(e) not in self.expected_errors[f.name]: warnings.warn('%s: %s' % (f.name, e)) else: raise Exception("Unexpected validation error: %s: %s" % (f.name, e)) # TODO uncomment below when validation errors have been fixed # raise Exception('%d validation error(s). See warnings.' % len(errors)) def test_read_timeseries_no_data(self): """Test that a TimeSeries written without data is read with data set to the default value.""" f = Path(__file__).parent / '1.5.1_timeseries_no_data.nwb' with NWBHDF5IO(str(f), 'r') as io: read_nwbfile = io.read() np.testing.assert_array_equal(read_nwbfile.acquisition['test_timeseries'].data, TimeSeries.DEFAULT_DATA) def test_read_timeseries_no_unit(self): """Test that an ImageSeries written without unit is read with unit set to the default value.""" f = Path(__file__).parent / '1.5.1_timeseries_no_unit.nwb' with NWBHDF5IO(str(f), 'r') as io: read_nwbfile = io.read() self.assertEqual(read_nwbfile.acquisition['test_timeseries'].unit, TimeSeries.DEFAULT_UNIT) def test_read_imageseries_no_data(self): """Test that an ImageSeries written without data is read with data set to the default value.""" f = Path(__file__).parent / '1.5.1_imageseries_no_data.nwb' with NWBHDF5IO(str(f), 'r') as io: read_nwbfile = io.read() np.testing.assert_array_equal(read_nwbfile.acquisition['test_imageseries'].data, ImageSeries.DEFAULT_DATA) def test_read_imageseries_no_unit(self): """Test that an ImageSeries written without unit is read with unit set to the default value.""" f = Path(__file__).parent / '1.5.1_imageseries_no_unit.nwb' with NWBHDF5IO(str(f), 'r') as io: read_nwbfile = io.read() self.assertEqual(read_nwbfile.acquisition['test_imageseries'].unit, ImageSeries.DEFAULT_UNIT) def test_read_imageseries_non_external_format(self): """Test that reading an ImageSeries with an inconsistent format does not change the value.""" fbase = "2.1.0_imageseries_non_external_format.nwb" f = Path(__file__).parent / fbase expected_warning = self.expected_warnings[fbase][0] with self.assertWarnsWith(UserWarning, expected_warning): with NWBHDF5IO(str(f), 'r') as io: read_nwbfile = io.read() self.assertEqual(read_nwbfile.acquisition['test_imageseries'].format, "tiff") def test_read_imageseries_nonmatch_starting_frame(self): """Test that reading an ImageSeries with an inconsistent starting_frame does not change the value.""" fbase = "2.1.0_imageseries_nonmatch_starting_frame.nwb" f = Path(__file__).parent / fbase expected_warning = self.expected_warnings[fbase][0] with self.assertWarnsWith(UserWarning, expected_warning): with NWBHDF5IO(str(f), 'r') as io: read_nwbfile = io.read() np.testing.assert_array_equal(read_nwbfile.acquisition['test_imageseries'].starting_frame, [1, 2, 3]) def test_read_subject_no_age__reference(self): """Test that reading a Subject without an age__reference set with NWB schema 2.5.0 sets the value to None""" f = Path(__file__).parent / '2.2.0_subject_no_age__reference.nwb' with NWBHDF5IO(str(f), 'r') as io: read_nwbfile = io.read() self.assertIsNone(read_nwbfile.subject.age__reference) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5540276 pynwb-2.5.0/tests/coverage/0000755000175100001730000000000014467767767015252 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/coverage/runCoverage0000755000175100001730000000044714467767506017454 0ustar00runnerdocker#!/bin/ksh # use default coverage name COV=coverage3 cd ../.. echo "" echo "Running Tests with Coverage:" ${COV} run --source=. test.py echo "" echo "Creating HTML output:" ${COV} html -d tests/coverage/htmlcov echo "" echo "Open /coverage/htmlcov/index.html to see results." echo "" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5540276 pynwb-2.5.0/tests/integration/0000755000175100001730000000000014467767767016002 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/__init__.py0000644000175100001730000000000014467767506020070 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5540276 pynwb-2.5.0/tests/integration/hdf5/0000755000175100001730000000000014467767767016630 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/__init__.py0000644000175100001730000000000014467767506020716 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_base.py0000644000175100001730000000416114467767506021144 0ustar00runnerdockerimport numpy as np from datetime import datetime from dateutil.tz import tzlocal from pynwb import TimeSeries, NWBFile, NWBHDF5IO from pynwb.base import Images, Image, ImageReferences from pynwb.testing import AcquisitionH5IOMixin, TestCase, remove_test_file class TestTimeSeriesIO(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return the test TimeSeries to read/write """ return TimeSeries( name='test_timeseries', data=list(range(1000)), unit='SIunit', timestamps=np.arange(1000.), resolution=0.1, continuity='continuous', ) class TestTimeSeriesLinking(TestCase): def setUp(self): self.path = 'test_timestamps_linking.nwb' def tearDown(self): remove_test_file(self.path) def test_timestamps_linking(self): ''' Test that timestamps get linked to in TimeSeries ''' tsa = TimeSeries(name='a', data=np.linspace(0, 1, 1000), timestamps=np.arange(1000.), unit='m') tsb = TimeSeries(name='b', data=np.linspace(0, 1, 1000), timestamps=tsa, unit='m') nwbfile = NWBFile(identifier='foo', session_start_time=datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal()), session_description='bar') nwbfile.add_acquisition(tsa) nwbfile.add_acquisition(tsb) with NWBHDF5IO(self.path, 'w') as io: io.write(nwbfile) with NWBHDF5IO(self.path, 'r') as io: nwbfile = io.read() tsa = nwbfile.acquisition['a'] tsb = nwbfile.acquisition['b'] self.assertIs(tsa.timestamps, tsb.timestamps) class TestImagesIO(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return the test Images to read/write """ image1 = Image(name='test_image', data=np.ones((10, 10))) image2 = Image(name='test_image2', data=np.ones((10, 10))) image_references = ImageReferences(name='order_of_images', data=[image2, image1]) images = Images(name='images_name', images=[image1, image2], order_of_images=image_references) return images ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_device.py0000644000175100001730000000120614467767506021466 0ustar00runnerdockerfrom pynwb.device import Device from pynwb.testing import NWBH5IOMixin, TestCase class TestDeviceIO(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test Device to read/write """ return Device(name='device_name', description='description', manufacturer='manufacturer') def addContainer(self, nwbfile): """ Add the test Device to the given NWBFile """ nwbfile.add_device(self.container) def getContainer(self, nwbfile): """ Return the test Device from the given NWBFile """ return nwbfile.get_device(self.container.name) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_ecephys.py0000644000175100001730000002655314467767506021703 0ustar00runnerdockerfrom hdmf.common import DynamicTableRegion from pynwb.ecephys import ( ElectrodeGroup, ElectricalSeries, FilteredEphys, LFP, Clustering, ClusterWaveforms, SpikeEventSeries, EventWaveform, EventDetection, FeatureExtraction, ) from pynwb.device import Device from pynwb.file import ElectrodeTable as get_electrode_table from pynwb.testing import NWBH5IOMixin, AcquisitionH5IOMixin, TestCase class TestElectrodeGroupIO(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test ElectrodeGroup to read/write """ self.dev1 = Device(name='dev1') eg = ElectrodeGroup(name='elec1', description='a test ElectrodeGroup', location='a nonexistent place', device=self.dev1) return eg def addContainer(self, nwbfile): """ Add the test ElectrodeGroup to the given NWBFile """ nwbfile.add_device(self.dev1) nwbfile.add_electrode_group(self.container) def getContainer(self, nwbfile): """ Return the test ElectrodeGroup from the given NWBFile """ return nwbfile.get_electrode_group(self.container.name) class TestElectricalSeriesIO(AcquisitionH5IOMixin, TestCase): @staticmethod def make_electrode_table(self): """ Make an electrode table, electrode group, and device """ self.table = get_electrode_table() self.dev1 = Device(name='dev1') self.group = ElectrodeGroup(name='tetrode1', description='tetrode description', location='tetrode location', device=self.dev1) for i in range(4): self.table.add_row(location='CA1', group=self.group, group_name='tetrode1') def setUpContainer(self): """ Return the test ElectricalSeries to read/write """ self.make_electrode_table(self) region = DynamicTableRegion(name='electrodes', data=[0, 2], description='the first and third electrodes', table=self.table) data = list(zip(range(10), range(10, 20))) timestamps = list(map(lambda x: x/10., range(10))) channel_conversion = [1., 2., 3., 4.] filtering = 'Low-pass filter at 300 Hz' es = ElectricalSeries( name='test_eS', data=data, electrodes=region, channel_conversion=channel_conversion, filtering=filtering, timestamps=timestamps ) return es def addContainer(self, nwbfile): """ Add the test ElectricalSeries and related objects to the given NWBFile """ nwbfile.add_device(self.dev1) nwbfile.add_electrode_group(self.group) nwbfile.set_electrode_table(self.table) nwbfile.add_acquisition(self.container) def test_eg_ref(self): """ Test that the electrode DynamicTableRegion references of the read ElectricalSeries have a group that correctly resolves to ElectrodeGroup instances. """ read = self.roundtripContainer() row1 = read.electrodes[0] row2 = read.electrodes[1] self.assertIsInstance(row1.iloc[0]['group'], ElectrodeGroup) self.assertIsInstance(row2.iloc[0]['group'], ElectrodeGroup) class MultiElectricalSeriesIOMixin(AcquisitionH5IOMixin): """ Mixin class for methods to run a roundtrip test writing an NWB file with multiple ElectricalSeries. The abstract method setUpContainer needs to be implemented by classes that include this mixin. def setUpContainer(self): # return a test Container to read/write """ def setUpTwoElectricalSeries(self): """ Return two test ElectricalSeries to read/write """ TestElectricalSeriesIO.make_electrode_table(self) region1 = DynamicTableRegion(name='electrodes', data=[0, 2], description='the first and third electrodes', table=self.table) region2 = DynamicTableRegion(name='electrodes', data=[1, 3], description='the second and fourth electrodes', table=self.table) data1 = list(zip(range(10), range(10, 20))) data2 = list(zip(reversed(range(10)), reversed(range(10, 20)))) timestamps = list(map(lambda x: x/10., range(10))) es1 = ElectricalSeries(name='test_eS1', data=data1, electrodes=region1, timestamps=timestamps) es2 = ElectricalSeries(name='test_eS2', data=data2, electrodes=region2, channel_conversion=[4., .4], timestamps=timestamps) return es1, es2 def addContainer(self, nwbfile): """ Add the test ElectricalSeries and related objects to the given NWBFile """ nwbfile.add_device(self.dev1) nwbfile.add_electrode_group(self.group) nwbfile.set_electrode_table(self.table) nwbfile.add_acquisition(self.container) class TestLFPIO(MultiElectricalSeriesIOMixin, TestCase): def setUpContainer(self): """ Return a test LFP to read/write """ es = self.setUpTwoElectricalSeries() lfp = LFP(es) return lfp class TestFilteredEphysIO(MultiElectricalSeriesIOMixin, TestCase): def setUpContainer(self): """ Return a test FilteredEphys to read/write """ es = self.setUpTwoElectricalSeries() fe = FilteredEphys(es) return fe class TestClusteringIO(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return a test Clustering to read/write """ with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): return Clustering("A fake Clustering interface", [0, 1, 2, 0, 1, 2], [100., 101., 102.], [float(i) for i in range(10, 61, 10)]) def roundtripContainer(self, cache_spec=False): # catch the DeprecationWarning raised when reading the Clustering object from file with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): return super().roundtripContainer(cache_spec) def roundtripExportContainer(self, cache_spec=False): # catch the DeprecationWarning raised when reading the Clustering object from file with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): return super().roundtripExportContainer(cache_spec) class EventWaveformConstructor(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return a test EventWaveform to read/write """ TestElectricalSeriesIO.make_electrode_table(self) region = DynamicTableRegion(name='electrodes', data=[0, 2], description='the first and third electrodes', table=self.table) sES = SpikeEventSeries(name='test_sES', data=((1, 1), (2, 2), (3, 3)), timestamps=[0., 1., 2.], electrodes=region) ew = EventWaveform(sES) return ew def addContainer(self, nwbfile): """ Add the test EventWaveform and related objects to the given NWBFile """ nwbfile.add_device(self.dev1) nwbfile.add_electrode_group(self.group) nwbfile.set_electrode_table(self.table) nwbfile.add_acquisition(self.container) class ClusterWaveformsConstructor(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return a test ClusterWaveforms to read/write """ times = [1.3, 2.3] num = [3, 4] peak_over_rms = [5.3, 6.3] with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): self.clustering = Clustering('description', num, peak_over_rms, times) means = [[7.3, 7.3]] stdevs = [[8.3, 8.3]] with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): cw = ClusterWaveforms(self.clustering, 'filtering', means, stdevs) return cw def addContainer(self, nwbfile): """ Add the test ClusterWaveforms and related objects to the given NWBFile """ nwbfile.add_acquisition(self.clustering) nwbfile.add_acquisition(self.container) def roundtripContainer(self, cache_spec=False): # catch the DeprecationWarning raised when reading the Clustering object from file with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): return super().roundtripContainer(cache_spec) def roundtripExportContainer(self, cache_spec=False): # catch the DeprecationWarning raised when reading the Clustering object from file with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): return super().roundtripExportContainer(cache_spec) class FeatureExtractionConstructor(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return a test FeatureExtraction to read/write """ event_times = [1.9, 3.5] TestElectricalSeriesIO.make_electrode_table(self) region = DynamicTableRegion(name='electrodes', data=[0, 2], description='the first and third electrodes', table=self.table) description = ['desc1', 'desc2', 'desc3'] features = [[[0., 1., 2.], [3., 4., 5.]], [[6., 7., 8.], [9., 10., 11.]]] fe = FeatureExtraction(electrodes=region, description=description, times=event_times, features=features) return fe def addContainer(self, nwbfile): """ Add the test FeatureExtraction and related objects to the given NWBFile """ nwbfile.add_device(self.dev1) nwbfile.add_electrode_group(self.group) nwbfile.set_electrode_table(self.table) nwbfile.add_acquisition(self.container) class EventDetectionConstructor(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return a test EventDetection to read/write """ TestElectricalSeriesIO.make_electrode_table(self) region = DynamicTableRegion(name='electrodes', data=[0, 2], description='the first and third electrodes', table=self.table) data = list(range(10)) ts = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] self.eS = ElectricalSeries(name='test_eS', data=data, electrodes=region, timestamps=ts) eD = EventDetection(detection_method='detection_method', source_electricalseries=self.eS, source_idx=(1, 2, 3), times=(0.1, 0.2, 0.3)) return eD def addContainer(self, nwbfile): """ Add the test EventDetection and related objects to the given NWBFile """ nwbfile.add_device(self.dev1) nwbfile.add_electrode_group(self.group) nwbfile.set_electrode_table(self.table) nwbfile.add_acquisition(self.eS) nwbfile.add_acquisition(self.container) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_icephys.py0000644000175100001730000003271314467767506021702 0ustar00runnerdockerimport numpy as np from pynwb import NWBFile from pynwb.icephys import (IntracellularElectrode, PatchClampSeries, CurrentClampStimulusSeries, SweepTable, VoltageClampStimulusSeries, CurrentClampSeries, VoltageClampSeries, IZeroClampSeries) from pynwb.device import Device from pynwb.testing import NWBH5IOMixin, AcquisitionH5IOMixin, TestCase import warnings class TestIntracellularElectrode(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test IntracellularElectrode to read/write """ self.device = Device(name='device_name') elec = IntracellularElectrode( name="elec0", slice='tissue slice', resistance='something measured in ohms', seal='sealing method', description='a fake electrode object', location='Springfield Elementary School', filtering='a meaningless free-form text field', initial_access_resistance='I guess this changes', device=self.device, cell_id="this_cell", ) return elec def addContainer(self, nwbfile): """ Add the test IntracellularElectrode and Device to the given NWBFile """ nwbfile.add_icephys_electrode(self.container) nwbfile.add_device(self.device) def getContainer(self, nwbfile): """ Return the test IntracellularElectrode from the given NWBFile """ return nwbfile.get_icephys_electrode(self.container.name) class TestPatchClampSeries(AcquisitionH5IOMixin, TestCase): def setUpElectrode(self): """ Set up the test IntracellularElectrode """ self.device = Device(name='device_name') self.elec = IntracellularElectrode(name="elec0", slice='tissue slice', resistance='something measured in ohms', seal='sealing method', description='a fake electrode object', location='Springfield Elementary School', filtering='a meaningless free-form text field', initial_access_resistance='I guess this changes', device=self.device) def setUpContainer(self): """ Return the test PatchClampSeries to read/write """ self.setUpElectrode() return PatchClampSeries(name="pcs", data=[1, 2, 3, 4, 5], unit='A', starting_time=123.6, rate=10e3, electrode=self.elec, gain=0.126, stimulus_description="gotcha ya!", sweep_number=np.uint(4711)) def addContainer(self, nwbfile): """ Add the test PatchClampSeries as an acquisition and IntracellularElectrode and Device to the given NWBFile """ nwbfile.add_icephys_electrode(self.elec) nwbfile.add_device(self.device) super().addContainer(nwbfile) class TestCurrentClampStimulusSeries(TestPatchClampSeries): def setUpContainer(self): """ Return the test CurrentClampStimulusSeries to read/write """ self.setUpElectrode() return CurrentClampStimulusSeries(name="ccss", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=self.elec, gain=0.126) class TestVoltageClampStimulusSeries(TestPatchClampSeries): def setUpContainer(self): """ Return the test VoltageClampStimulusSeries to read/write """ self.setUpElectrode() return VoltageClampStimulusSeries(name="vcss", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=self.elec, gain=0.126) class TestCurrentClampSeries(TestPatchClampSeries): def setUpContainer(self): """ Return the test CurrentClampSeries to read/write """ self.setUpElectrode() return CurrentClampSeries(name="ccs", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=self.elec, gain=0.126, bias_current=1.2, bridge_balance=2.3, capacitance_compensation=3.45) class TestVoltageClampSeries(TestPatchClampSeries): def setUpContainer(self): """ Return the test VoltageClampSeries to read/write """ self.setUpElectrode() return VoltageClampSeries(name="vcs", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=self.elec, gain=0.126, capacitance_fast=1.2, capacitance_slow=2.3, resistance_comp_bandwidth=3.45, resistance_comp_correction=4.5, resistance_comp_prediction=5.678, whole_cell_capacitance_comp=6.789, whole_cell_series_resistance_comp=0.7) class TestIZeroClampSeries(TestPatchClampSeries): def setUpContainer(self): """ Return the test IZeroClampSeries to read/write """ self.setUpElectrode() return IZeroClampSeries(name="izcs", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=self.elec, gain=0.126) class TestSweepTableRoundTripEasy(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test SweepTable to read/write """ self.device = Device(name='device_name') self.elec = IntracellularElectrode(name="elec0", slice='tissue slice', resistance='something measured in ohms', seal='sealing method', description='a fake electrode object', location='Springfield Elementary School', filtering='a meaningless free-form text field', initial_access_resistance='I guess this changes', device=self.device) self.pcs = PatchClampSeries(name="pcs", data=[1, 2, 3, 4, 5], unit='A', starting_time=123.6, rate=10e3, electrode=self.elec, gain=0.126, stimulus_description="gotcha ya!", sweep_number=np.uint(4711)) # Create the SweepTable but ignore the DeprecationWarning with warnings.catch_warnings(record=True) as w: warnings.simplefilter('ignore', DeprecationWarning) sweeptable = SweepTable(name='sweep_table') # Reissue any other warnings that may have occurred for i in w: warnings.warn(i.message, i.category) return sweeptable def addContainer(self, nwbfile): """ Add the test SweepTable, PatchClampSeries, IntracellularElectrode, and Device to the given NWBFile """ nwbfile.sweep_table = self.container nwbfile.add_device(self.device) nwbfile.add_icephys_electrode(self.elec) nwbfile.add_acquisition(self.pcs, use_sweep_table=True) def getContainer(self, nwbfile): """ Return the test SweepTable from the given NWBFile """ return nwbfile.sweep_table def roundtripContainer(self, cache_spec=False): # catch the DeprecationWarning raised when reading the SweepTable object from file with self.assertWarnsWith(DeprecationWarning, "Use of SweepTable is deprecated. Use the IntracellularRecordingsTable instead. " "See also the NWBFile.add_intracellular_recordings function."): return super().roundtripContainer(cache_spec) def roundtripExportContainer(self, cache_spec=False): # catch the DeprecationWarning raised when reading the SweepTable object from file with self.assertWarnsWith(DeprecationWarning, "Use of SweepTable is deprecated. Use the IntracellularRecordingsTable instead. " "See also the NWBFile.add_intracellular_recordings function."): return super().roundtripExportContainer(cache_spec) def test_container(self): """ Test properties of the SweepTable read from file """ description = 'a file to test writing and reading a %s' % self.container_type identifier = 'TEST_%s' % self.container_type nwbfile = NWBFile(description, identifier, self.start_time, file_create_date=self.create_date) self.addContainer(nwbfile) sweep_table = self.getContainer(nwbfile) self.assertEqual(len(sweep_table['series'].data), 1) self.assertEqual(sweep_table.id[0], 0) self.assertEqual(sweep_table['sweep_number'].data[0], 4711) class TestSweepTableRoundTripComplicated(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test SweepTable to read/write """ self.device = Device(name='device_name') self.elec = IntracellularElectrode(name="elec0", slice='tissue slice', resistance='something measured in ohms', seal='sealing method', description='a fake electrode object', location='Springfield Elementary School', filtering='a meaningless free-form text field', initial_access_resistance='I guess this changes', device=self.device) self.pcs1 = PatchClampSeries(name="pcs1", data=[1, 2, 3, 4, 5], unit='A', starting_time=123.6, rate=10e3, electrode=self.elec, gain=0.126, stimulus_description="gotcha ya!", sweep_number=np.uint(4711)) self.pcs2a = PatchClampSeries(name="pcs2a", data=[1, 2, 3, 4, 5], unit='A', starting_time=123.6, rate=10e3, electrode=self.elec, gain=0.126, stimulus_description="gotcha ya!", sweep_number=np.uint(4712)) self.pcs2b = PatchClampSeries(name="pcs2b", data=[1, 2, 3, 4, 5], unit='A', starting_time=123.6, rate=10e3, electrode=self.elec, gain=0.126, stimulus_description="gotcha ya!", sweep_number=np.uint(4712)) # Create the SweepTable but ignore the DeprecationWarning with warnings.catch_warnings(record=True) as w: warnings.simplefilter('ignore', DeprecationWarning) sweeptable = SweepTable(name='sweep_table') # Reissue any other warnings that may have occurred for i in w: warnings.warn(i.message, i.category) return sweeptable def addContainer(self, nwbfile): """ Add the test SweepTable, PatchClampSeries, IntracellularElectrode, and Device to the given NWBFile """ nwbfile.sweep_table = self.container nwbfile.add_device(self.device) nwbfile.add_icephys_electrode(self.elec) nwbfile.add_acquisition(self.pcs1, use_sweep_table=True) nwbfile.add_stimulus_template(self.pcs2a, use_sweep_table=True) nwbfile.add_stimulus(self.pcs2b, use_sweep_table=True) def getContainer(self, nwbfile): """ Return the test SweepTable from the given NWBFile """ return nwbfile.sweep_table def roundtripContainer(self, cache_spec=False): # catch the DeprecationWarning raised when reading the SweepTable object from file with self.assertWarnsWith(DeprecationWarning, "Use of SweepTable is deprecated. Use the IntracellularRecordingsTable instead. " "See also the NWBFile.add_intracellular_recordings function."): return super().roundtripContainer(cache_spec) def roundtripExportContainer(self, cache_spec=False): # catch the DeprecationWarning raised when reading the SweepTable object from file with self.assertWarnsWith(DeprecationWarning, "Use of SweepTable is deprecated. Use the IntracellularRecordingsTable instead. " "See also the NWBFile.add_intracellular_recordings function."): return super().roundtripExportContainer(cache_spec) def test_container(self): """ Test properties of the SweepTable read from file """ description = 'a file to test writing and reading a %s' % self.container_type identifier = 'TEST_%s' % self.container_type nwbfile = NWBFile(description, identifier, self.start_time, file_create_date=self.create_date) self.addContainer(nwbfile) sweep_table = self.getContainer(nwbfile) self.assertEqual(len(sweep_table['series'].data), 3) self.assertEqual(sweep_table['sweep_number'].data[0], 4711) self.assertEqual(sweep_table['sweep_number'].data[1], 4712) self.assertEqual(sweep_table['sweep_number'].data[2], 4712) series = sweep_table.get_series(4711) self.assertEqual(len(series), 1) names = [elem.name for elem in series] self.assertEqual(names, ["pcs1"]) sweep_numbers = [elem.sweep_number for elem in series] self.assertEqual(sweep_numbers, [4711]) series = sweep_table.get_series(4712) self.assertEqual(len(series), 2) names = [elem.name for elem in series] self.assertEqual(names, ["pcs2a", "pcs2b"]) sweep_numbers = [elem.sweep_number for elem in series] self.assertEqual(sweep_numbers, [4712, 4712]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_image.py0000644000175100001730000000326514467767506021320 0ustar00runnerdockerimport numpy as np from pynwb.device import Device from pynwb.image import ImageSeries, OpticalSeries from pynwb.testing import AcquisitionH5IOMixin, NWBH5IOMixin, TestCase class TestImageSeriesIO(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return a test ImageSeries to read/write """ self.dev1 = Device('dev1') iS = ImageSeries( name='test_iS', unit='unit', external_file=['external_file'], starting_frame=[0], format='external', timestamps=[1., 2., 3.], device=self.dev1, ) return iS def addContainer(self, nwbfile): """ Add the test ElectrodeGroup to the given NWBFile """ nwbfile.add_device(self.dev1) super().addContainer(nwbfile) class TestOpticalSeriesIO(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return a test OpticalSeries to read/write """ self.dev1 = Device('dev1') self.optical_series = OpticalSeries( name='OpticalSeries', distance=8., field_of_view=(4., 5.), orientation='upper left', data=np.ones((10, 3, 3)), unit='m', format='raw', timestamps=np.arange(10.), device=self.dev1, ) return self.optical_series def addContainer(self, nwbfile): """ Add the test OpticalSeries to the given NWBFile """ nwbfile.add_device(self.dev1) nwbfile.add_stimulus(self.optical_series) def getContainer(self, nwbfile): """ Return the test OpticalSeries from the given NWBFile """ return nwbfile.stimulus['OpticalSeries'] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_io.py0000644000175100001730000006107314467767506020646 0ustar00runnerdockerfrom datetime import datetime from dateutil.tz import tzlocal, tzutc import numpy as np from h5py import File from pathlib import Path from pynwb import NWBFile, TimeSeries, get_manager, NWBHDF5IO, validate from hdmf.backends.io import UnsupportedOperation from hdmf.backends.hdf5 import HDF5IO, H5DataIO from hdmf.data_utils import DataChunkIterator from hdmf.build import GroupBuilder, DatasetBuilder from hdmf.spec import NamespaceCatalog from pynwb.spec import NWBGroupSpec, NWBDatasetSpec, NWBNamespace from pynwb.ecephys import ElectricalSeries, LFP from pynwb.testing import remove_test_file, TestCase class TestHDF5Writer(TestCase): _required_tests = ('test_nwbio', 'test_write_clobber', 'test_write_cache_spec', 'test_write_no_cache_spec') @property def required_tests(self): return self._required_tests def setUp(self): self.manager = get_manager() self.path = "test_pynwb_io_hdf5.nwb" self.start_time = datetime(1970, 1, 1, 12, tzinfo=tzutc()) self.create_date = datetime(2017, 4, 15, 12, tzinfo=tzlocal()) self.container = NWBFile(session_description='a test NWB File', identifier='TEST123', session_start_time=self.start_time, file_create_date=self.create_date) ts = TimeSeries(name='test_timeseries', data=list(range(100, 200, 10)), unit='SIunit', timestamps=np.arange(10.), resolution=0.1) self.container.add_acquisition(ts) ts_builder = GroupBuilder('test_timeseries', attributes={'neurodata_type': 'TimeSeries'}, datasets={'data': DatasetBuilder('data', list(range(100, 200, 10)), attributes={'unit': 'SIunit', 'conversion': 1.0, 'resolution': 0.1}), 'timestamps': DatasetBuilder('timestamps', np.arange(10.), attributes={'unit': 'seconds', 'interval': 1})}) self.builder = GroupBuilder( 'root', groups={'acquisition': GroupBuilder('acquisition', groups={'test_timeseries': ts_builder}), 'analysis': GroupBuilder('analysis'), 'general': GroupBuilder('general'), 'processing': GroupBuilder('processing'), 'stimulus': GroupBuilder( 'stimulus', groups={'presentation': GroupBuilder('presentation'), 'templates': GroupBuilder('templates')})}, datasets={'file_create_date': DatasetBuilder('file_create_date', [self.create_date.isoformat()]), 'identifier': DatasetBuilder('identifier', 'TEST123'), 'session_description': DatasetBuilder('session_description', 'a test NWB File'), 'nwb_version': DatasetBuilder('nwb_version', '1.0.6'), 'session_start_time': DatasetBuilder('session_start_time', self.start_time.isoformat())}, attributes={'neurodata_type': 'NWBFile'}) def tearDown(self): remove_test_file(self.path) def test_nwbio(self): with HDF5IO(self.path, manager=self.manager, mode='a') as io: io.write(self.container) with File(self.path, 'r') as f: self.assertIn('acquisition', f) self.assertIn('analysis', f) self.assertIn('general', f) self.assertIn('processing', f) self.assertIn('file_create_date', f) self.assertIn('identifier', f) self.assertIn('session_description', f) self.assertIn('session_start_time', f) acq = f.get('acquisition') self.assertIn('test_timeseries', acq) def test_write_clobber(self): with HDF5IO(self.path, manager=self.manager, mode='a') as io: io.write(self.container) with self.assertRaisesWith(UnsupportedOperation, "Unable to open file %s in 'w-' mode. File already exists." % self.path): with HDF5IO(self.path, manager=self.manager, mode='w-') as io: pass def test_write_cache_spec(self): ''' Round-trip test for writing spec and reading it back in ''' with HDF5IO(self.path, manager=self.manager, mode="a") as io: io.write(self.container) with File(self.path, 'r') as f: self.assertIn('specifications', f) ns_catalog = NamespaceCatalog(NWBGroupSpec, NWBDatasetSpec, NWBNamespace) HDF5IO.load_namespaces(ns_catalog, self.path) original_ns = self.manager.namespace_catalog.get_namespace('core') cached_ns = ns_catalog.get_namespace('core') self.maxDiff = None for key in ('author', 'contact', 'doc', 'full_name', 'name'): with self.subTest(namespace_field=key): self.assertEqual(original_ns[key], cached_ns[key]) for dt in original_ns.get_registered_types(): with self.subTest(neurodata_type=dt): original_spec = original_ns.get_spec(dt) cached_spec = cached_ns.get_spec(dt) with self.subTest(test='data_type spec read back in'): self.assertIsNotNone(cached_spec) with self.subTest(test='cached spec preserved original spec'): self.assertDictEqual(original_spec, cached_spec) def test_write_no_cache_spec(self): ''' Round-trip test for not writing spec ''' with HDF5IO(self.path, manager=self.manager, mode="a") as io: io.write(self.container, cache_spec=False) with File(self.path, 'r') as f: self.assertNotIn('specifications', f) class TestHDF5WriterWithInjectedFile(TestCase): _required_tests = ('test_nwbio', 'test_write_clobber', 'test_write_cache_spec') @property def required_tests(self): return self._required_tests def setUp(self): self.manager = get_manager() self.path = "test_pynwb_io_hdf5_injected.nwb" self.start_time = datetime(1970, 1, 1, 12, tzinfo=tzutc()) self.create_date = datetime(2017, 4, 15, 12, tzinfo=tzlocal()) self.container = NWBFile(session_description='a test NWB File', identifier='TEST123', session_start_time=self.start_time, file_create_date=self.create_date) ts = TimeSeries(name='test_timeseries', data=list(range(100, 200, 10)), unit='SIunit', timestamps=np.arange(10.), resolution=0.1) self.container.add_acquisition(ts) ts_builder = GroupBuilder('test_timeseries', attributes={'neurodata_type': 'TimeSeries'}, datasets={'data': DatasetBuilder('data', list(range(100, 200, 10)), attributes={'unit': 'SIunit', 'conversion': 1.0, 'resolution': 0.1}), 'timestamps': DatasetBuilder('timestamps', np.arange(10.), attributes={'unit': 'seconds', 'interval': 1})}) self.builder = GroupBuilder( 'root', groups={'acquisition': GroupBuilder('acquisition', groups={'test_timeseries': ts_builder}), 'analysis': GroupBuilder('analysis'), 'general': GroupBuilder('general'), 'processing': GroupBuilder('processing'), 'stimulus': GroupBuilder( 'stimulus', groups={'presentation': GroupBuilder('presentation'), 'templates': GroupBuilder('templates')})}, datasets={'file_create_date': DatasetBuilder('file_create_date', [self.create_date.isoformat()]), 'identifier': DatasetBuilder('identifier', 'TEST123'), 'session_description': DatasetBuilder('session_description', 'a test NWB File'), 'nwb_version': DatasetBuilder('nwb_version', '1.0.6'), 'session_start_time': DatasetBuilder('session_start_time', self.start_time.isoformat())}, attributes={'neurodata_type': 'NWBFile'}) def tearDown(self): remove_test_file(self.path) def test_nwbio(self): with File(self.path, 'w') as fil: with HDF5IO(self.path, manager=self.manager, file=fil, mode='a') as io: io.write(self.container) with File(self.path, 'r') as f: self.assertIn('acquisition', f) self.assertIn('analysis', f) self.assertIn('general', f) self.assertIn('processing', f) self.assertIn('file_create_date', f) self.assertIn('identifier', f) self.assertIn('session_description', f) self.assertIn('session_start_time', f) acq = f.get('acquisition') self.assertIn('test_timeseries', acq) def test_write_clobber(self): with File(self.path, 'w') as fil: with HDF5IO(self.path, manager=self.manager, file=fil, mode='a') as io: io.write(self.container) with self.assertRaisesWith(UnsupportedOperation, "Unable to open file %s in 'w-' mode. File already exists." % self.path): with HDF5IO(self.path, manager=self.manager, mode='w-') as io: pass def test_write_cache_spec(self): ''' Round-trip test for writing spec and reading it back in ''' with File(self.path, 'w') as fil: with HDF5IO(self.path, manager=self.manager, file=fil, mode='a') as io: io.write(self.container) with File(self.path, 'r') as f: self.assertIn('specifications', f) ns_catalog = NamespaceCatalog(NWBGroupSpec, NWBDatasetSpec, NWBNamespace) HDF5IO.load_namespaces(ns_catalog, self.path) original_ns = self.manager.namespace_catalog.get_namespace('core') cached_ns = ns_catalog.get_namespace('core') self.maxDiff = None for key in ('author', 'contact', 'doc', 'full_name', 'name'): with self.subTest(namespace_field=key): self.assertEqual(original_ns[key], cached_ns[key]) for dt in original_ns.get_registered_types(): with self.subTest(neurodata_type=dt): original_spec = original_ns.get_spec(dt) cached_spec = cached_ns.get_spec(dt) with self.subTest(test='data_type spec read back in'): self.assertIsNotNone(cached_spec) with self.subTest(test='cached spec preserved original spec'): self.assertDictEqual(original_spec, cached_spec) class TestAppend(TestCase): def setUp(self): self.nwbfile = NWBFile(session_description='hi', identifier='hi', session_start_time=datetime(1970, 1, 1, 12, tzinfo=tzutc())) self.path = "test_append.nwb" def tearDown(self): remove_test_file(self.path) def test_append(self): proc_mod = self.nwbfile.create_processing_module(name='test_proc_mod', description='') proc_inter = LFP(name='LFP') proc_mod.add(proc_inter) device = self.nwbfile.create_device(name='test_device') e_group = self.nwbfile.create_electrode_group( name='test_electrode_group', description='', location='', device=device ) self.nwbfile.add_electrode(x=0.0, y=0.0, z=0.0, imp=np.nan, location='loc', filtering='filt', group=e_group) electrodes = self.nwbfile.create_electrode_table_region(region=[0], description='') e_series = ElectricalSeries( name='test_es', electrodes=electrodes, data=np.ones(shape=(100,)), rate=10000.0, ) proc_inter.add_electrical_series(e_series) with NWBHDF5IO(self.path, mode='w') as io: io.write(self.nwbfile, cache_spec=False) with NWBHDF5IO(self.path, mode='a') as io: nwb = io.read() link_electrodes = nwb.processing['test_proc_mod']['LFP'].electrical_series['test_es'].electrodes ts2 = ElectricalSeries(name='timeseries2', data=[4., 5., 6.], rate=1.0, electrodes=link_electrodes) nwb.add_acquisition(ts2) io.write(nwb) # also attempt to write same spec again self.assertIs(nwb.processing['test_proc_mod']['LFP'].electrical_series['test_es'].electrodes, nwb.acquisition['timeseries2'].electrodes) with NWBHDF5IO(self.path, mode='r') as io: nwb = io.read() np.testing.assert_equal(nwb.acquisition['timeseries2'].data[:], ts2.data) self.assertIs(nwb.processing['test_proc_mod']['LFP'].electrical_series['test_es'].electrodes, nwb.acquisition['timeseries2'].electrodes) errors = validate(io) self.assertEqual(len(errors), 0, errors) def test_electrode_id_uniqueness(self): device = self.nwbfile.create_device(name='test_device') e_group = self.nwbfile.create_electrode_group(name='test_electrode_group', description='', location='', device=device) self.nwbfile.add_electrode(id=0, x=0.0, y=0.0, z=0.0, imp=np.nan, location='loc', filtering='filt', group=e_group) with self.assertRaises(ValueError): self.nwbfile.add_electrode(id=0, x=0.0, y=0.0, z=0.0, imp=np.nan, location='loc', filtering='filt', group=e_group) class TestH5DataIO(TestCase): """ Test that H5DataIO functions correctly on round trip with the HDF5IO backend """ def setUp(self): self.nwbfile = NWBFile(session_description='a', identifier='b', session_start_time=datetime(1970, 1, 1, 12, tzinfo=tzutc())) self.path = "test_pynwb_io_hdf5_h5dataIO.h5" def tearDown(self): remove_test_file(self.path) def test_gzip_timestamps(self): ts = TimeSeries(name='ts_name', data=[1, 2, 3], unit='A', timestamps=H5DataIO(np.array([1., 2., 3.]), compression='gzip')) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile, cache_spec=False) # confirm that the dataset was indeed compressed with File(self.path, 'r') as f: self.assertEqual(f['/acquisition/ts_name/timestamps'].compression, 'gzip') def test_write_dataset_custom_compress(self): a = H5DataIO(np.arange(30).reshape(5, 2, 3), compression='gzip', compression_opts=5, shuffle=True, fletcher32=True) ts = TimeSeries(name='ts_name', data=a, unit='A', timestamps=np.arange(5.)) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile, cache_spec=False) with File(self.path, 'r') as f: dset = f['/acquisition/ts_name/data'] self.assertTrue(np.all(dset[:] == a.data)) self.assertEqual(dset.compression, 'gzip') self.assertEqual(dset.compression_opts, 5) self.assertEqual(dset.shuffle, True) self.assertEqual(dset.fletcher32, True) def test_write_dataset_custom_chunks(self): a = H5DataIO(np.arange(30).reshape(5, 2, 3), chunks=(1, 1, 3)) ts = TimeSeries(name='ts_name', data=a, unit='A', timestamps=np.arange(5.)) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile, cache_spec=False) with File(self.path, 'r') as f: dset = f['/acquisition/ts_name/data'] self.assertTrue(np.all(dset[:] == a.data)) self.assertEqual(dset.chunks, (1, 1, 3)) def test_write_dataset_custom_fillvalue(self): a = H5DataIO(np.arange(20).reshape(5, 4), fillvalue=-1) ts = TimeSeries(name='ts_name', data=a, unit='A', timestamps=np.arange(5.)) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile, cache_spec=False) with File(self.path, 'r') as f: dset = f['/acquisition/ts_name/data'] self.assertTrue(np.all(dset[:] == a.data)) self.assertEqual(dset.fillvalue, -1) def test_write_dataset_datachunkiterator_data_and_time(self): a = np.arange(30).reshape(5, 2, 3) aiter = iter(a) daiter = DataChunkIterator.from_iterable(aiter, buffer_size=2) tstamps = np.arange(5.) tsiter = DataChunkIterator.from_iterable(tstamps) ts = TimeSeries(name='ts_name', data=daiter, unit='A', timestamps=tsiter) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile, cache_spec=False) with File(self.path, 'r') as f: dset = f['/acquisition/ts_name/data'] self.assertListEqual(dset[:].tolist(), a.tolist()) def test_write_dataset_datachunkiterator_data_only(self): a = np.arange(30).reshape(5, 2, 3) aiter = iter(a) daiter = DataChunkIterator.from_iterable(aiter, buffer_size=2) tstamps = np.arange(5.) ts = TimeSeries(name='ts_name', data=daiter, unit='A', timestamps=tstamps) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile, cache_spec=False) with File(self.path, 'r') as f: dset = f['/acquisition/ts_name/data'] self.assertListEqual(dset[:].tolist(), a.tolist()) def test_write_dataset_datachunkiterator_with_compression(self): a = np.arange(30).reshape(5, 2, 3) aiter = iter(a) daiter = DataChunkIterator.from_iterable(aiter, buffer_size=2) wrapped_daiter = H5DataIO(data=daiter, compression='gzip', compression_opts=5, shuffle=True, fletcher32=True) ts = TimeSeries(name='ts_name', data=wrapped_daiter, unit='A', timestamps=np.arange(5.)) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile, cache_spec=False) with File(self.path, 'r') as f: dset = f['/acquisition/ts_name/data'] self.assertEqual(dset.shape, a.shape) self.assertListEqual(dset[:].tolist(), a.tolist()) self.assertEqual(dset.compression, 'gzip') self.assertEqual(dset.compression_opts, 5) self.assertEqual(dset.shuffle, True) self.assertEqual(dset.fletcher32, True) class TestNWBHDF5IO(TestCase): """Test that file io with NWBHDF5IO works correctly""" def setUp(self): self.nwbfile = NWBFile(session_description='a test NWB File', identifier='TEST123', session_start_time=datetime(1970, 1, 1, 12, tzinfo=tzutc())) self.path = "test_pynwb_io_nwbhdf5.h5" def tearDown(self): remove_test_file(self.path) def test_nwb_version_property(self): """Test reading of files with missing nwb_version""" # check empty version before write with NWBHDF5IO(self.path, 'w') as io: self.assertTupleEqual(io.nwb_version, (None, None)) # write the example file with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile) # check behavior for various different version strings for ver in [("2.0.5", (2, 0, 5)), ("2.0.5-alpha", (2, 0, 5, "alpha")), ("1.0.4_beta", (1, 0, 4, "beta")), ("bad_version", ("bad", "version", ))]: # Set version string with File(self.path, mode='a') as io: io.attrs['nwb_version'] = ver[0] # Assert expected result for nwb_version tuple with NWBHDF5IO(self.path, 'r') as io: self.assertEqual(io.nwb_version[0], ver[0]) self.assertTupleEqual(io.nwb_version[1], ver[1]) # check empty version attribute with File(self.path, mode='a') as io: del io.attrs['nwb_version'] with NWBHDF5IO(self.path, 'r') as io: self.assertTupleEqual(io.nwb_version, (None, None)) # check that it works when setting the attribute to a fixed-length numpy-bytes string with File(self.path, mode='a') as io: io.attrs['nwb_version'] = np.asarray("2.0.5", dtype=np.bytes_)[()] with NWBHDF5IO(self.path, 'r') as io: self.assertTupleEqual(io.nwb_version, ("2.0.5", (2, 0, 5))) def test_check_nwb_version_ok(self): """Test that opening a current NWBFile passes the version check""" with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile) with NWBHDF5IO(self.path, 'r') as io: self.assertIsNotNone(io.nwb_version[0]) self.assertIsNotNone(io.nwb_version[1]) self.assertGreater(io.nwb_version[1][0], 1) read_file = io.read() self.assertContainerEqual(read_file, self.nwbfile) def test_check_nwb_version_missing_version(self): """Test reading of files with missing nwb_version""" # write the example file with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile) # remove the version attribute with File(self.path, mode='a') as io: del io.attrs['nwb_version'] # test that reading the file without a version strings fails with self.assertRaisesWith( TypeError, "Missing NWB version in file. The file is not a valid NWB file."): with NWBHDF5IO(self.path, 'r') as io: _ = io.read() # test that reading the file when skipping the version check works with NWBHDF5IO(self.path, 'r') as io: read_file = io.read(skip_version_check=True) self.assertContainerEqual(read_file, self.nwbfile) def test_check_nwb_version_old_version(self): """Test reading of files with version less than 2 """ # write the example file with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile) # remove the version attribute with File(self.path, mode='a') as io: io.attrs['nwb_version'] = "1.0.5" # test that reading the file without a version strings fails with self.assertRaisesWith( TypeError, "NWB version 1.0.5 not supported. PyNWB supports NWB files version 2 and above."): with NWBHDF5IO(self.path, 'r') as io: _ = io.read() # test that reading the file when skipping the version check works with NWBHDF5IO(self.path, 'r') as io: read_file = io.read(skip_version_check=True) self.assertContainerEqual(read_file, self.nwbfile) def test_round_trip_with_path_string(self): """Opening a NWBHDF5IO with a path string should work correctly""" path_str = self.path with NWBHDF5IO(path_str, 'w') as io: io.write(self.nwbfile) with NWBHDF5IO(path_str, 'r') as io: read_file = io.read() self.assertContainerEqual(read_file, self.nwbfile) def test_round_trip_with_pathlib_path(self): """Opening a NWBHDF5IO with a pathlib path should correctly""" pathlib_path = Path(self.path) with NWBHDF5IO(pathlib_path, 'w') as io: io.write(self.nwbfile) with NWBHDF5IO(pathlib_path, 'r') as io: read_file = io.read() self.assertContainerEqual(read_file, self.nwbfile) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_misc.py0000644000175100001730000002064114467767506021166 0ustar00runnerdockerimport numpy as np from hdmf.common import DynamicTable, VectorData, DynamicTableRegion from pynwb import TimeSeries from pynwb.misc import Units, DecompositionSeries from pynwb.testing import NWBH5IOMixin, AcquisitionH5IOMixin, TestCase from pynwb.ecephys import ElectrodeGroup from pynwb.device import Device from pynwb.file import ElectrodeTable as get_electrode_table class TestUnitsIO(AcquisitionH5IOMixin, TestCase): """ Test adding Units into acquisition and accessing Units after read """ def setUpContainer(self): """ Return the test Units to read/write """ ut = Units(name='UnitsTest', description='a simple table for testing Units') ut.add_unit(spike_times=[0., 1., 2.], obs_intervals=[[0., 1.], [2., 3.]], waveform_mean=[1., 2., 3.], waveform_sd=[4., 5., 6.], waveforms=[ [ # elec 1 [1, 2, 3], [1, 2, 3], [1, 2, 3] ], [ # elec 2 [1, 2, 3], [1, 2, 3], [1, 2, 3] ] ]) ut.add_unit(spike_times=[3., 4., 5.], obs_intervals=[[2., 5.], [6., 7.]], waveform_mean=[1., 2., 3.], waveform_sd=[4., 5., 6.], waveforms=np.array([ [ # elec 1 [1, 2, 3], # spike 1, [sample 1, sample 2, sample 3] [1, 2, 3], # spike 2 [1, 2, 3], # spike 3 [1, 2, 3] # spike 4 ], [ # elec 2 [1, 2, 3], # spike 1 [1, 2, 3], # spike 2 [1, 2, 3], # spike 3 [1, 2, 3] # spike 4 ], [ # elec 3 [1, 2, 3], # spike 1 [1, 2, 3], # spike 2 [1, 2, 3], # spike 3 [1, 2, 3] # spike 4 ] ])) ut.waveform_rate = 40000. ut.resolution = 1/40000 return ut def test_get_spike_times(self): """ Test whether the Units spike times read from file are what was written """ ut = self.roundtripContainer() received = ut.get_unit_spike_times(0) np.testing.assert_array_equal(received, [0., 1., 2.]) received = ut.get_unit_spike_times(1) np.testing.assert_array_equal(received, [3., 4., 5.]) np.testing.assert_array_equal(ut['spike_times'][:], [[0., 1., 2.], [3., 4., 5.]]) def test_get_obs_intervals(self): """ Test whether the Units observation intervals read from file are what was written """ ut = self.roundtripContainer() received = ut.get_unit_obs_intervals(0) np.testing.assert_array_equal(received, [[0., 1.], [2., 3.]]) received = ut.get_unit_obs_intervals(1) np.testing.assert_array_equal(received, [[2., 5.], [6., 7.]]) np.testing.assert_array_equal(ut['obs_intervals'][:], [[[0., 1.], [2., 3.]], [[2., 5.], [6., 7.]]]) class TestUnitsFileIO(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return placeholder Units object. Tested units are added directly to the NWBFile in addContainer """ return Units('placeholder') # this will get ignored def addContainer(self, nwbfile): """ Add units to the given NWBFile """ device = nwbfile.create_device(name='trodes_rig123') electrode_name = 'tetrode1' description = "an example tetrode" location = "somewhere in the hippocampus" electrode_group = nwbfile.create_electrode_group(electrode_name, description=description, location=location, device=device) for idx in [1, 2, 3, 4]: nwbfile.add_electrode(id=idx, location='CA1', group=electrode_group) nwbfile.add_unit(id=1, electrodes=[1], electrode_group=electrode_group) nwbfile.add_unit(id=2, electrodes=[1], electrode_group=electrode_group) self.container = nwbfile.units # override self.container which has the placeholder def getContainer(self, nwbfile): """ Return the test Units from the given NWBFile """ return nwbfile.units def test_to_dataframe(self): units = self.roundtripContainer() units.to_dataframe() class TestDecompositionSeriesIO(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test DecompositionSeries to read/write """ self.timeseries = TimeSeries(name='dummy timeseries', description='desc', data=np.ones((3, 3)), unit='flibs', timestamps=np.ones((3,))) bands = DynamicTable(name='bands', description='band info for LFPSpectralAnalysis', columns=[ VectorData(name='band_name', description='name of bands', data=['alpha', 'beta', 'gamma']), VectorData(name='band_limits', description='low and high cutoffs in Hz', data=np.ones((3, 2))) ]) spec_anal = DecompositionSeries(name='LFPSpectralAnalysis', description='my description', data=np.ones((3, 3, 3)), timestamps=np.ones((3,)), source_timeseries=self.timeseries, metric='amplitude', bands=bands) return spec_anal def addContainer(self, nwbfile): """ Add the test DecompositionSeries to the given NWBFile in a processing module """ nwbfile.add_acquisition(self.timeseries) prcs_mod = nwbfile.create_processing_module('test_mod', 'test_mod') prcs_mod.add(self.container) def getContainer(self, nwbfile): """ Return the test DecompositionSeries from the given NWBFile """ return nwbfile.processing['test_mod']['LFPSpectralAnalysis'] class TestDecompositionSeriesWithSourceChannelsIO(AcquisitionH5IOMixin, TestCase): @staticmethod def make_electrode_table(self): """ Make an electrode table, electrode group, and device """ self.table = get_electrode_table() self.dev1 = Device(name='dev1') self.group = ElectrodeGroup(name='tetrode1', description='tetrode description', location='tetrode location', device=self.dev1) for i in range(4): self.table.add_row(location='CA1', group=self.group, group_name='tetrode1') def setUpContainer(self): """ Return the test ElectricalSeries to read/write """ self.make_electrode_table(self) region = DynamicTableRegion(name='source_channels', data=[0, 2], description='the first and third electrodes', table=self.table) data = np.random.randn(100, 2, 30) timestamps = np.arange(100)/100 ds = DecompositionSeries(name='test_DS', data=data, source_channels=region, timestamps=timestamps, metric='amplitude') return ds def addContainer(self, nwbfile): """ Add the test ElectricalSeries and related objects to the given NWBFile """ nwbfile.add_device(self.dev1) nwbfile.add_electrode_group(self.group) nwbfile.set_electrode_table(self.table) nwbfile.add_acquisition(self.container) def test_eg_ref(self): """ Test that the electrode DynamicTableRegion references of the read ElectricalSeries have a group that correctly resolves to ElectrodeGroup instances. """ read = self.roundtripContainer() row1 = read.source_channels[0] row2 = read.source_channels[1] self.assertIsInstance(row1.iloc[0]['group'], ElectrodeGroup) self.assertIsInstance(row2.iloc[0]['group'], ElectrodeGroup) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_modular_storage.py0000644000175100001730000001476314467767506023432 0ustar00runnerdockerimport os import gc from datetime import datetime from dateutil.tz import tzutc import numpy as np from hdmf.backends.hdf5 import HDF5IO from hdmf.backends.hdf5.h5_utils import H5DataIO from pynwb import get_manager, NWBFile, NWBHDF5IO, TimeSeries, validate as pynwb_validate from pynwb.testing import remove_test_file, TestCase class TestTimeSeriesModular(TestCase): def setUp(self): self.start_time = datetime(1971, 1, 1, 12, tzinfo=tzutc()) self.data = np.arange(2000).reshape((1000, 2)) self.timestamps = np.linspace(0, 1, 1000) self.container = TimeSeries( name='data_ts', unit='V', data=self.data, timestamps=self.timestamps ) self.data_filename = os.path.join(os.getcwd(), 'test_time_series_modular_data.nwb') self.link_filename = os.path.join(os.getcwd(), 'test_time_series_modular_link.nwb') self.read_container = None self.link_read_io = None self.data_read_io = None def tearDown(self): if self.read_container: self.read_container.data.file.close() self.read_container.timestamps.file.close() if self.link_read_io: self.link_read_io.close() if self.data_read_io: self.data_read_io.close() # necessary to remove all references to the file and garbage # collect on windows in order to be able to truncate/overwrite # the file later. see pynwb GH issue #975 if os.name == 'nt': gc.collect() remove_test_file(self.link_filename) remove_test_file(self.data_filename) def roundtripContainer(self): # create and write data file data_file = NWBFile( session_description='a test file', identifier='data_file', session_start_time=self.start_time ) data_file.add_acquisition(self.container) with HDF5IO(self.data_filename, 'w', manager=get_manager()) as data_write_io: data_write_io.write(data_file) # read data file with HDF5IO(self.data_filename, 'r', manager=get_manager()) as self.data_read_io: data_file_obt = self.data_read_io.read() # write "link file" with timeseries.data that is an external link to the timeseries in "data file" # also link timeseries.timestamps.data to the timeseries.timestamps in "data file" with HDF5IO(self.link_filename, 'w', manager=get_manager()) as link_write_io: link_file = NWBFile( session_description='a test file', identifier='link_file', session_start_time=self.start_time ) self.link_container = TimeSeries( name='test_mod_ts', unit='V', data=data_file_obt.get_acquisition('data_ts'), # test direct link timestamps=H5DataIO( data=data_file_obt.get_acquisition('data_ts').timestamps, link_data=True # test with setting link data ) ) link_file.add_acquisition(self.link_container) link_write_io.write(link_file) # note that self.link_container contains a link to a dataset that is now closed # read the link file self.link_read_io = HDF5IO(self.link_filename, 'r', manager=get_manager()) self.read_nwbfile = self.link_read_io.read() return self.getContainer(self.read_nwbfile) def test_roundtrip(self): self.read_container = self.roundtripContainer() # make sure we get a completely new object self.assertIsNotNone(str(self.container)) # added as a test to make sure printing works self.assertIsNotNone(str(self.link_container)) self.assertIsNotNone(str(self.read_container)) self.assertFalse(self.link_container.timestamps.valid) self.assertTrue(self.read_container.timestamps.id.valid) self.assertNotEqual(id(self.link_container), id(self.read_container)) self.assertIs(self.read_nwbfile.objects[self.link_container.object_id], self.read_container) self.assertContainerEqual(self.read_container, self.container, ignore_name=True, ignore_hdmf_attrs=True) self.assertEqual(self.read_container.object_id, self.link_container.object_id) self.validate() def test_link_root(self): # create and write data file data_file = NWBFile( session_description='a test file', identifier='data_file', session_start_time=self.start_time ) data_file.add_acquisition(self.container) with HDF5IO(self.data_filename, 'w', manager=get_manager()) as data_write_io: data_write_io.write(data_file) # read data file manager = get_manager() with HDF5IO(self.data_filename, 'r', manager=manager) as data_read_io: data_file_obt = data_read_io.read() link_file = NWBFile( session_description='a test file', identifier='link_file', session_start_time=self.start_time ) link_container = data_file_obt.acquisition[self.container.name] link_file.add_acquisition(link_container) self.assertIs(link_container.parent, data_file_obt) with HDF5IO(self.link_filename, 'w', manager=manager) as link_write_io: link_write_io.write(link_file) # read the link file, check container sources with HDF5IO(self.link_filename, 'r+', manager=get_manager()) as link_file_reader: read_nwbfile = link_file_reader.read() self.assertNotEqual(read_nwbfile.acquisition[self.container.name].container_source, read_nwbfile.container_source) self.assertEqual(read_nwbfile.acquisition[self.container.name].container_source, self.data_filename) self.assertEqual(read_nwbfile.container_source, self.link_filename) def validate(self): filenames = [self.data_filename, self.link_filename] for fn in filenames: if os.path.exists(fn): with NWBHDF5IO(fn, mode='r') as io: errors = pynwb_validate(io) if errors: for err in errors: raise Exception(err) def getContainer(self, nwbfile): return nwbfile.get_acquisition('test_mod_ts') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_nwbfile.py0000644000175100001730000006346314467767506021672 0ustar00runnerdockerfrom datetime import datetime from dateutil.tz import tzlocal, tzutc import pandas as pd import numpy as np from hdmf.backends.hdf5 import HDF5IO from hdmf.common import DynamicTable from pynwb import NWBFile, TimeSeries, NWBHDF5IO, get_manager from pynwb.base import Image, Images from pynwb.file import Subject from pynwb.epoch import TimeIntervals from pynwb.ecephys import ElectricalSeries from pynwb.testing import NWBH5IOMixin, NWBH5IOFlexMixin, TestCase, remove_test_file class TestNWBFileHDF5IO(TestCase): """ Test reading/writing an NWBFile using HDF5IO """ def setUp(self): """ Set up an NWBFile object with an acquisition TimeSeries, analysis TimeSeries, and a processing module """ self.start_time = datetime(1970, 1, 1, 12, tzinfo=tzutc()) self.ref_time = datetime(1979, 1, 1, 0, tzinfo=tzutc()) self.create_date = datetime(2017, 4, 15, 12, tzinfo=tzlocal()) self.manager = get_manager() self.filename = 'test_nwbfileio.h5' self.nwbfile = NWBFile(session_description='a test NWB File', identifier='TEST123', session_start_time=self.start_time, timestamps_reference_time=self.ref_time, file_create_date=self.create_date, experimenter='test experimenter', stimulus_notes='test stimulus notes', data_collection='test data collection notes', experiment_description='test experiment description', institution='nomad', lab='nolab', notes='nonotes', pharmacology='nopharmacology', protocol='noprotocol', related_publications='nopubs', session_id='007', slices='noslices', source_script='nosources', surgery='nosurgery', virus='novirus', source_script_file_name='nofilename') self.ts = TimeSeries(name='test_timeseries', data=list(range(100, 200, 10)), unit='SIunit', timestamps=np.arange(10.), resolution=0.1) self.nwbfile.add_acquisition(self.ts) self.ts2 = TimeSeries(name='test_timeseries2', data=list(range(200, 300, 10)), unit='SIunit', timestamps=np.arange(10.), resolution=0.1) self.nwbfile.add_analysis(self.ts2) self.mod = self.nwbfile.create_processing_module('test_module', 'a test module') self.ts3 = TimeSeries(name='test_timeseries2', data=list(range(100, 200, 10)), unit='SIunit', timestamps=np.arange(10.), resolution=0.1) self.mod.add(self.ts3) def tearDown(self): """ Delete the created test file """ remove_test_file(self.filename) def test_children(self): """ Test that the TimeSeries and processing module are children of their respective parents """ self.assertIn(self.ts, self.nwbfile.children) self.assertIn(self.ts2, self.nwbfile.children) self.assertIn(self.mod, self.nwbfile.children) self.assertIn(self.ts3, self.mod.children) def test_write(self): """ Test writing the NWBFile using HDF5IO """ hdf5io = HDF5IO(self.filename, manager=self.manager, mode='a') hdf5io.write(self.nwbfile) hdf5io.close() # TODO add some asserts def test_read(self): """ Test reading the NWBFile using HDF5IO """ hdf5io = HDF5IO(self.filename, manager=self.manager, mode='w') hdf5io.write(self.nwbfile) hdf5io.close() hdf5io = HDF5IO(self.filename, manager=self.manager, mode='r') container = hdf5io.read() self.assertIsInstance(container, NWBFile) self.assertEqual(len(container.acquisition), 1) self.assertEqual(len(container.analysis), 1) for v in container.acquisition.values(): self.assertIsInstance(v, TimeSeries) self.assertContainerEqual(container, self.nwbfile) hdf5io.close() class TestNWBFileIO(NWBH5IOMixin, TestCase): """ Test writing an NWBFile to disk and reading back the file """ # this uses methods tearDown, test_roundtrip, and validate from NWBH5IOMixin. the rest are overridden def setUp(self): super().setUp() self.start_time = datetime(1970, 1, 1, 12, tzinfo=tzutc()) self.ref_time = datetime(1979, 1, 1, 0, tzinfo=tzutc()) self.create_dates = [datetime(2017, 5, 1, 12, tzinfo=tzlocal()), datetime(2017, 5, 2, 13, 0, 0, 1, tzinfo=tzutc()), datetime(2017, 5, 2, 14, tzinfo=tzutc())] def setUpContainer(self): """ Return a placeholder NWBFile """ return NWBFile('placeholder', 'placeholder', datetime(1970, 1, 1, 12, tzinfo=tzutc())) def build_nwbfile(self): """ Create an NWB file """ self.container = NWBFile(session_description='a test session description for a test NWBFile', identifier='FILE123', session_start_time=self.start_time, file_create_date=self.create_dates, timestamps_reference_time=self.ref_time, experimenter='A test experimenter', lab='a test lab', institution='a test institution', experiment_description='a test experiment description', session_id='test1', notes='my notes', pharmacology='drugs', protocol='protocol', related_publications='my pubs', slices='my slices', surgery='surgery', virus='a virus', source_script='noscript', source_script_file_name='nofilename', stimulus_notes='test stimulus notes', data_collection='test data collection notes', keywords=('these', 'are', 'keywords')) def roundtripContainer(self, cache_spec=False): """ Build and write an NWBFile to disk, read the file, and return the NWBFile """ self.build_nwbfile() self.writer = NWBHDF5IO(self.filename, mode='w') self.writer.write(self.container, cache_spec=cache_spec) self.writer.close() self.reader = NWBHDF5IO(self.filename, mode='r') self.read_nwbfile = self.reader.read() return self.read_nwbfile def addContainer(self, nwbfile): """ No-op. roundtripContainer is overridden and no longer uses addContainer """ pass def getContainer(self, nwbfile): """ Get the NWBFile object from the given NWBFile """ return nwbfile class TestExperimentersConstructorRoundtrip(TestNWBFileIO): """ Test that a list of multiple experimenters in a constructor is written to and read from file """ def build_nwbfile(self): description = 'test nwbfile experimenter' identifier = 'TEST_experimenter' self.nwbfile = NWBFile(session_description=description, identifier=identifier, session_start_time=self.start_time, experimenter=('experimenter1', 'experimenter2')) class TestExperimentersSetterRoundtrip(TestNWBFileIO): """ Test that a list of multiple experimenters in a setter is written to and read from file """ def build_nwbfile(self): description = 'test nwbfile experimenter' identifier = 'TEST_experimenter' self.nwbfile = NWBFile(session_description=description, identifier=identifier, session_start_time=self.start_time) self.nwbfile.experimenter = ('experimenter1', 'experimenter2') class TestPublicationsConstructorRoundtrip(TestNWBFileIO): """ Test that a list of multiple publications in a constructor is written to and read from file """ def build_nwbfile(self): description = 'test nwbfile publications' identifier = 'TEST_publications' self.nwbfile = NWBFile(session_description=description, identifier=identifier, session_start_time=self.start_time, related_publications=('pub1', 'pub2')) class TestPublicationsSetterRoundtrip(TestNWBFileIO): """ Test that a list of multiple publications in a setter is written to and read from file """ def build_nwbfile(self): description = 'test nwbfile publications' identifier = 'TEST_publications' self.nwbfile = NWBFile(session_description=description, identifier=identifier, session_start_time=self.start_time) self.nwbfile.related_publications = ('pub1', 'pub2') class TestSubjectIO(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test Subject """ return Subject( age="P90D", age__reference="gestational", description="An unfortunate rat", genotype="WT", sex="M", species="Rattus norvegicus", subject_id="RAT123", weight="2 kg", date_of_birth=datetime(1970, 1, 1, 12, tzinfo=tzutc()), strain="my_strain", ) def addContainer(self, nwbfile): """ Add the test Subject to the given NWBFile """ nwbfile.subject = self.container def getContainer(self, nwbfile): """ Return the test Subject from the given NWBFile """ return nwbfile.subject class TestSubjectAgeReferenceNotSetIO(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test Subject """ return Subject( age="P90D", description="An unfortunate rat", genotype="WT", sex="M", species="Rattus norvegicus", subject_id="RAT123", weight="2 kg", date_of_birth=datetime(1970, 1, 1, 12, tzinfo=tzutc()), strain="my_strain", ) def addContainer(self, nwbfile): """ Add the test Subject to the given NWBFile """ nwbfile.subject = self.container def getContainer(self, nwbfile): """ Return the test Subject from the given NWBFile """ return nwbfile.subject class TestEmptySubjectIO(TestSubjectIO): def setUpContainer(self): return Subject() class TestEpochsIO(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return placeholder epochs object. Tested epochs are added directly to the NWBFile in addContainer """ return TimeIntervals('epochs') def addContainer(self, nwbfile): """ Add the test epochs to the given NWBFile """ nwbfile.add_epoch_column( name='temperature', description='average temperature (c) during epoch' ) nwbfile.add_epoch( start_time=5.3, stop_time=6.1, timeseries=[], tags='ambient', temperature=26.4, ) # reset the thing self.container = nwbfile.epochs def getContainer(self, nwbfile): """ Return the test epochs from the given NWBFile """ return nwbfile.epochs class TestEpochsIODf(TestEpochsIO): def addContainer(self, nwbfile): """ Add the test epochs with TimeSeries objects to the given NWBFile """ tsa, tsb = [ TimeSeries(name='a', data=np.arange(11), unit='flubs', timestamps=np.linspace(0, 1, 11)), TimeSeries(name='b', data=np.arange(13), unit='flubs', timestamps=np.linspace(0.1, 5, 13)), ] nwbfile.add_acquisition(tsa) nwbfile.add_acquisition(tsb) nwbfile.epochs = TimeIntervals.from_dataframe( pd.DataFrame({ 'foo': [1, 2, 3, 4], 'bar': ['fish', 'fowl', 'dog', 'cat'], 'start_time': [0.2, 0.25, 0.30, 0.35], 'stop_time': [0.25, 0.30, 0.40, 0.45], 'timeseries': [[(2, 1, tsa)], [(3, 1, tsa)], [(3, 1, tsa)], [(4, 1, tsa)]], 'tags': [[''], [''], ['fizz', 'buzz'], ['qaz']] }), 'epochs', columns=[ {'name': 'foo', 'description': 'a column of integers'}, {'name': 'bar', 'description': 'a column of strings'}, ] ) # reset the thing self.container = nwbfile.epochs def test_df_comparison(self): """ Test that the epochs read from file converted to a data frame are the same as the data frame converted from the original epochs and the timeseries columns within them are the same """ self.read_container = self.roundtripContainer() df_obt = self.read_container.to_dataframe() tsa = self.read_nwbfile.get_acquisition('a') df_exp = pd.DataFrame({ 'foo': [1, 2, 3, 4], 'bar': ['fish', 'fowl', 'dog', 'cat'], 'start_time': [0.2, 0.25, 0.30, 0.35], 'stop_time': [0.25, 0.30, 0.40, 0.45], 'timeseries': [[(2, 1, tsa)], [(3, 1, tsa)], [(3, 1, tsa)], [(4, 1, tsa)]], 'tags': [[''], [''], ['fizz', 'buzz'], ['qaz']] }, index=pd.Index(np.arange(4, dtype=np.int64), name='id') ) # pop the timeseries column out because ts_obt has rows of lists of tuples and ts_exp has rows of lists of lists ts_obt = df_obt.pop('timeseries') ts_exp = df_exp.pop('timeseries') pd.testing.assert_frame_equal(df_exp, df_obt, check_like=True, check_dtype=False) # check the timeseries columns match for ex, obt in zip(ts_exp, ts_obt): self.assertEqual(ex[0][0], obt[0][0]) self.assertEqual(ex[0][1], obt[0][1]) self.assertContainerEqual(ex[0][2], obt[0][2]) def test_df_comparison_no_ts(self): """ Test that the epochs read from file converted to a data frame are the same as the data frame converted from the original epochs without a timeseries column """ self.read_container = self.roundtripContainer() df_exp = pd.DataFrame({ 'foo': [1, 2, 3, 4], 'bar': ['fish', 'fowl', 'dog', 'cat'], 'start_time': [0.2, 0.25, 0.30, 0.35], 'stop_time': [0.25, 0.30, 0.40, 0.45], 'tags': [[''], [''], ['fizz', 'buzz'], ['qaz']] }, index=pd.Index(np.arange(4, dtype=np.int64), name='id') ) df_obt = self.read_container.to_dataframe(exclude=set(['timeseries', 'timeseries_index'])) pd.testing.assert_frame_equal(df_exp, df_obt, check_like=True, check_dtype=False) class TestTrials(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return placeholder Table for trials. Tested trials are added directly to the NWBFile in addContainer """ return DynamicTable(name='trials', description='a placeholder table') # this will get ignored def addContainer(self, nwbfile): """ Add trials and trial columns to the given NWBFile """ nwbfile.add_trial_column('foo', 'an int column') nwbfile.add_trial_column('bar', 'a float column') nwbfile.add_trial_column('baz', 'a string column') nwbfile.add_trial_column('qux', 'a boolean column') nwbfile.add_trial(start_time=0., stop_time=1., foo=27, bar=28.0, baz="29", qux=True) nwbfile.add_trial(start_time=2., stop_time=3., foo=37, bar=38.0, baz="39", qux=False) self.container = nwbfile.trials # override self.container which has the placeholder def getContainer(self, nwbfile): """ Return the test trials table from the given NWBFile """ return nwbfile.trials class TestInvalidTimes(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return placeholder Table for trials. Tested invalid times are added directly to the NWBFile in addContainer """ return DynamicTable(name='invalid times', description='a placeholder table') def addContainer(self, nwbfile): """ Add invalid times and invalid times columns to the given NWBFile """ nwbfile.add_invalid_times_column('foo', 'an int column') nwbfile.add_invalid_times_column('bar', 'a float column') nwbfile.add_invalid_times_column('baz', 'a string column') nwbfile.add_invalid_times_column('qux', 'a boolean column') nwbfile.add_invalid_time_interval(start_time=0., stop_time=1., foo=27, bar=28.0, baz="29", qux=True) nwbfile.add_invalid_time_interval(start_time=2., stop_time=3., foo=37, bar=38.0, baz="39", qux=False) self.container = nwbfile.invalid_times # override self.container which has the placeholder def getContainer(self, nwbfile): """ Return the test invalid times table from the given NWBFile """ return nwbfile.invalid_times class TestUnits(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return placeholder table for Units. Tested units are added directly to the NWBFile in addContainer """ return DynamicTable(name='units', description='a placeholder table') def addContainer(self, nwbfile): """ Add units and unit columns to the given NWBFile """ nwbfile.add_unit_column('foo', 'an int column') nwbfile.add_unit_column('my_bool', 'a bool column') nwbfile.add_unit(foo=27, my_bool=True) nwbfile.add_unit(foo=37, my_bool=False) self.container = nwbfile.units # override self.container which has the placeholder def getContainer(self, nwbfile): """ Return the test units table from the given NWBFile """ return nwbfile.units class TestDynamicTableFromDataframeIO(NWBH5IOMixin, TestCase): def setUpContainer(self): return DynamicTable.from_dataframe(pd.DataFrame({ 'a': [[1, 2, 3], [1, 2, 3], [1, 2, 3]], 'b': ['4', '5', '6'] }), 'test_table') def addContainer(self, nwbfile): test_mod = nwbfile.create_processing_module('test', 'desc') test_mod.add(self.container) def getContainer(self, nwbfile): dyn_tab = nwbfile.processing['test'].data_interfaces['test_table'] return dyn_tab def test_to_dataframe(self): dyn_tab = self.roundtripContainer() dyn_tab.to_dataframe() # also test 2D column round-trip class TestElectrodes(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return placeholder table for electrodes. Tested electrodes are added directly to the NWBFile in addContainer """ return DynamicTable(name='electrodes', description='a placeholder table') def addContainer(self, nwbfile): """ Add electrodes and related objects to the given NWBFile """ self.dev1 = nwbfile.create_device(name='dev1') self.group = nwbfile.create_electrode_group( name='tetrode1', description='tetrode description', location='tetrode location', device=self.dev1 ) nwbfile.add_electrode( id=1, x=1.0, y=2.0, z=3.0, imp=-1.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1' ) nwbfile.add_electrode( id=2, x=1.0, y=2.0, z=3.0, imp=-2.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1' ) self.container = nwbfile.electrodes # override self.container which has the placeholder def getContainer(self, nwbfile): """ Return the test electrodes table from the given NWBFile """ return nwbfile.electrodes def test_roundtrip(self): super().test_roundtrip() # When comparing the pandas dataframes for the row we drop the 'group' column since the # ElectrodeGroup object after reading will naturally have a different address pd.testing.assert_frame_equal(self.read_container[0].drop('group', axis=1), self.container[0].drop('group', axis=1)) class TestElectrodesOptColumns(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return placeholder table for electrodes. Tested electrodes are added directly to the NWBFile in addContainer """ return DynamicTable(name='electrodes', description='a placeholder table') def addContainer(self, nwbfile): """ Add electrodes and related objects to the given NWBFile """ self.dev1 = nwbfile.create_device(name='dev1') self.group = nwbfile.create_electrode_group( name='tetrode1', description='tetrode description', location='tetrode location', device=self.dev1 ) nwbfile.add_electrode( id=1, x=1.0, y=2.0, z=3.0, imp=-1.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1', rel_x=4.0, rel_y=5.0, rel_z=6.0, reference='ref1' ) nwbfile.add_electrode( id=2, x=1.0, y=2.0, z=3.0, imp=-2.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1', rel_x=4.0, rel_y=5.0, rel_z=6.0, reference='ref1' ) self.container = nwbfile.electrodes # override self.container which has the placeholder def getContainer(self, nwbfile): """ Return the test electrodes table from the given NWBFile """ return nwbfile.electrodes def test_roundtrip(self): super().test_roundtrip() # When comparing the pandas dataframes for the row we drop the 'group' column since the # ElectrodeGroup object after reading will naturally have a different address pd.testing.assert_frame_equal(self.read_container[0].drop('group', axis=1), self.container[0].drop('group', axis=1)) class TestElectrodesRegion(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return placeholder table for electrodes. Tested electrodes are added directly to the NWBFile in addContainer """ return DynamicTable(name='electrodes', description='a placeholder table') def addContainer(self, nwbfile): """ Add electrode table region and related objects to the given NWBFile """ self.dev1 = nwbfile.create_device(name='dev1') self.group = nwbfile.create_electrode_group(name='tetrode1', description='tetrode description', location='tetrode location', device=self.dev1) nwbfile.add_electrode(id=1, x=1.0, y=2.0, z=3.0, imp=-1.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1') nwbfile.add_electrode(id=2, x=1.0, y=2.0, z=3.0, imp=-2.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1') nwbfile.add_electrode(id=3, x=1.0, y=2.0, z=3.0, imp=-3.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1') nwbfile.add_electrode(id=4, x=1.0, y=2.0, z=3.0, imp=-4.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1') region = nwbfile.create_electrode_table_region( region=tuple([1, 2, 3]), name='electrodes', description='desc' ) nwbfile.add_acquisition(ElectricalSeries( name='test_data', data=np.arange(10), timestamps=np.arange(10.), electrodes=region )) self.container = region # override self.container which has the placeholder def getContainer(self, nwbfile): """ Return the test electrodes table from the given NWBFile """ self.table = nwbfile.electrodes return nwbfile.get_acquisition('test_data').electrodes def test_roundtrip(self): super().test_roundtrip() for ii, item in enumerate(self.read_container): pd.testing.assert_frame_equal(self.table[ii+1], item) class TestAddStimulusTemplateTimeSeries(NWBH5IOFlexMixin, TestCase): def getContainerType(self): return "time series stored as a stimulus template" def addContainer(self): ts = TimeSeries( name="test_ts", data=[0, 1, 2, 3, 4, 5], unit="grams", timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5] ) self.nwbfile.add_stimulus_template(ts) def getContainer(self, nwbfile): return nwbfile.get_stimulus_template("test_ts") class TestAddStimulusTemplateImages(NWBH5IOFlexMixin, TestCase): def getContainerType(self): return "images stored as a stimulus template" def addContainer(self): image1 = Image(name="test_image1", data=np.ones((10, 10))) images = Images(name="images_name", images=[image1]) self.nwbfile.add_stimulus_template(images) def getContainer(self, nwbfile): return nwbfile.get_stimulus_template("images_name") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_ogen.py0000644000175100001730000000343014467767506021160 0ustar00runnerdockerfrom pynwb.ogen import OptogeneticSeries, OptogeneticStimulusSite from pynwb.device import Device from pynwb.testing import NWBH5IOMixin, AcquisitionH5IOMixin, TestCase class TestOptogeneticStimulusSiteIO(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test OptogeneticStimulusSite to read/write """ self.device = Device(name='dev1') return OptogeneticStimulusSite(name='stim_site', device=self.device, description='my stim site', excitation_lambda=300., location='in the brain') def addContainer(self, nwbfile): """ Add the test OptogeneticStimulusSite and Device to the given NWBFile """ nwbfile.add_device(self.device) nwbfile.add_ogen_site(self.container) def getContainer(self, nwbfile): """ Return the test OptogeneticStimulusSite from the given NWBFile """ return nwbfile.get_ogen_site(self.container.name) class TestOptogeneticSeriesIO(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return the test OptogeneticSeries to read/write """ self.device = Device(name='dev1') self.ogen_stim_site = OptogeneticStimulusSite(name='stim_site', device=self.device, description='my stim site', excitation_lambda=300., location='in the brain') return OptogeneticSeries(name='stim_series', data=[1., 2., 3.], site=self.ogen_stim_site, rate=100.) def addContainer(self, nwbfile): """ Add the test OptogeneticSeries as an acquisition and add Device and OptogeneticStimulusSite to the given NWBFile """ nwbfile.add_device(self.device) nwbfile.add_ogen_site(self.ogen_stim_site) nwbfile.add_acquisition(self.container) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_ophys.py0000644000175100001730000003314114467767506021374 0ustar00runnerdockerfrom abc import ABCMeta from copy import deepcopy import numpy as np from pynwb.ophys import ( ImagingPlane, OpticalChannel, PlaneSegmentation, ImageSegmentation, OnePhotonSeries, TwoPhotonSeries, RoiResponseSeries, MotionCorrection, CorrectedImageStack, ) from pynwb.base import TimeSeries from pynwb.image import ImageSeries from pynwb.device import Device from pynwb.testing import NWBH5IOMixin, AcquisitionH5IOMixin, TestCase def make_imaging_plane(): """ Make an ImagingPlane and related objects """ device = Device(name='dev1') optical_channel = OpticalChannel( name='optchan1', description='a fake OpticalChannel', emission_lambda=500. ) imaging_plane = ImagingPlane( name='imgpln1', optical_channel=optical_channel, description='a fake ImagingPlane', device=device, excitation_lambda=600., imaging_rate=300., indicator='GFP', location='somewhere in the brain', reference_frame='unknown' ) return device, optical_channel, imaging_plane class TestImagingPlaneIO(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test ImagingPlane to read/write """ self.device = Device(name='dev1') self.optical_channel = OpticalChannel( name='optchan1', description='a fake OpticalChannel', emission_lambda=500. ) return ImagingPlane( name='imgpln1', optical_channel=self.optical_channel, description='a fake ImagingPlane', device=self.device, excitation_lambda=600., imaging_rate=300., indicator='GFP', location='somewhere in the brain', reference_frame='unknown', origin_coords=[10., 20.], origin_coords_unit='millimeters', grid_spacing=[0.001, 0.001], grid_spacing_unit='millimeters', ) def addContainer(self, nwbfile): """ Add the test ImagingPlane and Device to the given NWBFile """ nwbfile.add_device(self.device) nwbfile.add_imaging_plane(self.container) def getContainer(self, nwbfile): """ Return the test ImagingPlane from the given NWBFile """ return nwbfile.get_imaging_plane(self.container.name) class TestMotionCorrection(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test ImagingPlane to read/write """ self.device, self.optical_channel, self.imaging_plane = make_imaging_plane() self.two_photon_series = TwoPhotonSeries( name='TwoPhotonSeries', data=np.ones((1000, 100, 100)), imaging_plane=self.imaging_plane, rate=1.0, unit='normalized amplitude' ) corrected = ImageSeries( name='corrected', data=np.ones((1000, 100, 100)), unit='na', format='raw', starting_time=0.0, rate=1.0 ) xy_translation = TimeSeries( name='xy_translation', data=np.ones((1000, 2)), unit='pixels', starting_time=0.0, rate=1.0, ) corrected_image_stack = CorrectedImageStack( corrected=corrected, original=self.two_photon_series, xy_translation=xy_translation, ) return MotionCorrection(corrected_image_stacks=[corrected_image_stack]) def addContainer(self, nwbfile): """ Add the test ImagingPlane and Device to the given NWBFile """ nwbfile.add_device(self.device) nwbfile.add_imaging_plane(self.imaging_plane) nwbfile.add_acquisition(self.two_photon_series) ophys_module = nwbfile.create_processing_module( name='ophys', description='optical physiology processed data' ) ophys_module.add(self.container) def getContainer(self, nwbfile): """ Return the test ImagingPlane from the given NWBFile """ return nwbfile.processing['ophys'].data_interfaces['MotionCorrection'] class TestOnePhotonSeriesIO(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return the test OnePhotonSeries to read/write """ self.device, self.optical_channel, self.imaging_plane = make_imaging_plane() data = np.ones((10, 2, 2)) timestamps = list(map(lambda x: x/10, range(10))) ret = OnePhotonSeries( name='test_2ps', imaging_plane=self.imaging_plane, data=data, unit='image_unit', format='raw', pmt_gain=1.7, scan_line_rate=3.4, exposure_time=123., binning=2, power=9001., intensity=5., timestamps=timestamps, dimension=[2], ) return ret def addContainer(self, nwbfile): """ Add the test OnePhotonSeries as an acquisition and add Device and ImagingPlane to the given NWBFile """ nwbfile.add_device(self.device) nwbfile.add_imaging_plane(self.imaging_plane) nwbfile.add_acquisition(self.container) class TestTwoPhotonSeriesIO(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return the test TwoPhotonSeries to read/write """ self.device, self.optical_channel, self.imaging_plane = make_imaging_plane() data = np.ones((10, 2, 2)) timestamps = list(map(lambda x: x/10, range(10))) fov = [2.0, 2.0, 5.0] ret = TwoPhotonSeries( name='test_2ps', imaging_plane=self.imaging_plane, data=data, unit='image_unit', format='raw', field_of_view=fov, pmt_gain=1.7, scan_line_rate=3.4, timestamps=timestamps, dimension=[2] ) return ret def addContainer(self, nwbfile): """ Add the test TwoPhotonSeries as an acquisition and add Device and ImagingPlane to the given NWBFile """ nwbfile.add_device(self.device) nwbfile.add_imaging_plane(self.imaging_plane) nwbfile.add_acquisition(self.container) class TestPlaneSegmentationIO(NWBH5IOMixin, TestCase): @staticmethod def buildPlaneSegmentation(self): """ Return an PlaneSegmentation and set related objects """ w, h = 5, 5 img_mask = [[[1.0 for x in range(w)] for y in range(h)], [[2.0 for x in range(w)] for y in range(h)]] pix_mask = [(1, 2, 1.0), (3, 4, 1.0), (5, 6, 1.0), (7, 8, 2.0), (9, 10, 2.)] ts = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9] self.image_series = ImageSeries( name='test_iS', dimension=[2], external_file=['images.tiff'], starting_frame=[0], format='external', timestamps=ts ) self.device = Device(name='dev1') self.optical_channel = OpticalChannel( name='test_optical_channel', description='optical channel description', emission_lambda=500. ) self.imaging_plane = ImagingPlane( name='imgpln1', optical_channel=self.optical_channel, description='a fake ImagingPlane', device=self.device, excitation_lambda=600., imaging_rate=300., indicator='GFP', location='somewhere in the brain', reference_frame='unknown' ) self.img_mask = deepcopy(img_mask) self.pix_mask = deepcopy(pix_mask) self.pxmsk_index = [3, 5] pS = PlaneSegmentation( description='plane segmentation description', imaging_plane=self.imaging_plane, name='test_plane_seg_name', reference_images=self.image_series ) pS.add_roi(pixel_mask=pix_mask[0:3], image_mask=img_mask[0]) pS.add_roi(pixel_mask=pix_mask[3:5], image_mask=img_mask[1]) return pS def setUpContainer(self): """ Return the test PlaneSegmentation to read/write """ return self.buildPlaneSegmentation(self) def addContainer(self, nwbfile): """ Add an ImageSegmentation in processing with a PlaneSegmentation and add Device and ImagingPlane to the given NWBFile """ nwbfile.add_device(self.device) nwbfile.add_imaging_plane(self.imaging_plane) img_seg = ImageSegmentation() img_seg.add_plane_segmentation(self.container) self.mod = nwbfile.create_processing_module(name='plane_seg_test_module', description='a plain module for testing') self.mod.add(img_seg) def getContainer(self, nwbfile): """ Return the test PlaneSegmentation from the given NWBFile """ mod = nwbfile.get_processing_module(self.mod.name) img_seg = mod.get('ImageSegmentation') return img_seg.get_plane_segmentation(self.container.name) class MaskIO(TestPlaneSegmentationIO, metaclass=ABCMeta): def buildPlaneSegmentationNoRois(self): """ Return an PlaneSegmentation and set related objects """ ts = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9] self.image_series = ImageSeries( name='test_iS', dimension=[2], external_file=['images.tiff'], starting_frame=[0], format='external', timestamps=ts ) self.device = Device(name='dev1') self.optical_channel = OpticalChannel( name='test_optical_channel', description='optical channel description', emission_lambda=500. ) self.imaging_plane = ImagingPlane( name='test_imaging_plane', optical_channel=self.optical_channel, description='imaging plane description', device=self.device, excitation_lambda=600., imaging_rate=300., indicator='GFP', location='somewhere in the brain', reference_frame='a frame to refer to' ) return PlaneSegmentation( description='description', imaging_plane=self.imaging_plane, name='test_plane_seg_name', reference_images=self.image_series ) class TestPixelMaskIO(MaskIO): def setUpContainer(self): """ Return the test PlaneSegmentation with pixel mask ROIs to read/write """ pix_mask = [(1, 2, 1.0), (3, 4, 1.0), (5, 6, 1.0), (7, 8, 2.0), (9, 10, 2.)] pS = self.buildPlaneSegmentationNoRois() pS.add_roi(pixel_mask=pix_mask[0:3]) pS.add_roi(pixel_mask=pix_mask[3:5]) return pS class TestImageMaskIO(MaskIO): def setUpContainer(self): """ Return the test PlaneSegmentation with voxel mask ROIs to read/write """ w, h = 5, 5 img_mask = [[[1.0 for x in range(w)] for y in range(h)], [[2.0 for x in range(w)] for y in range(h)]] pS = self.buildPlaneSegmentationNoRois() pS.add_roi(image_mask=img_mask[0]) pS.add_roi(image_mask=img_mask[1]) return pS class TestRoiResponseSeriesIO(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return the test RoiResponseSeries to read/write """ self.plane_segmentation = TestPlaneSegmentationIO.buildPlaneSegmentation(self) self.rt_region = self.plane_segmentation.create_roi_table_region('the first of two ROIs', region=[0]) data = [0., 1., 2., 3., 4., 5., 6., 7., 8., 9.] timestamps = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9] return RoiResponseSeries( name='test_roi_response_series', data=data, rois=self.rt_region, unit='lumens', timestamps=timestamps ) def addContainer(self, nwbfile): """ Add the test RoiResponseSeries as an acquisition and add Device, ImagingPlane, ImageSegmentation, and PlaneSegmentation to the given NWBFile """ nwbfile.add_device(self.device) nwbfile.add_imaging_plane(self.imaging_plane) img_seg = ImageSegmentation() img_seg.add_plane_segmentation(self.plane_segmentation) mod = nwbfile.create_processing_module(name='plane_seg_test_module', description='a plain module for testing') mod.add(img_seg) super().addContainer(nwbfile) class TestCorrectedImageStackIO(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """Return the test CorrectedImageStack to read/write.""" timestamps = [1., 2.] corrected_is = ImageSeries( name='corrected', unit='unit', external_file=['external_file'], starting_frame=[0], format='external', timestamps=timestamps ) self.original_is = ImageSeries( name='original_is', unit='unit', external_file=['external_file'], starting_frame=[0], format='external', timestamps=timestamps ) tstamps = [1., 2., 3.] ts = TimeSeries( name='xy_translation', data=list(range(len(tstamps))), unit='unit', timestamps=tstamps ) return CorrectedImageStack( corrected=corrected_is, original=self.original_is, xy_translation=ts ) def addContainer(self, nwbfile): """Add the test CorrectedImageStack and the original ImageSeries in acquisition.""" nwbfile.add_acquisition(self.original_is) super().addContainer(nwbfile) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_retinotopy.py0000644000175100001730000000334014467767506022444 0ustar00runnerdocker# import numpy as np # # from pynwb.retinotopy import ImagingRetinotopy, AxisMap, RetinotopyImage, FocalDepthImage, RetinotopyMap # from pynwb.testing import AcquisitionH5IOMixin, TestCase # # # class TestImagingRetinotopy(AcquisitionH5IOMixin, TestCase): # # def setUpContainer(self): # """ Return the test ImagingRetinotopy to read/write """ # data = np.ones((2, 2)) # field_of_view = [1, 2] # dimension = [1, 2] # sign_map = RetinotopyMap('sign_map', data, field_of_view, dimension) # axis_1_phase_map = AxisMap('axis_1_phase_map', data, field_of_view, 'unit', dimension) # axis_1_power_map = AxisMap('axis_1_power_map', data, field_of_view, 'unit', dimension) # axis_2_phase_map = AxisMap('axis_2_phase_map', data, field_of_view, 'unit', dimension) # axis_2_power_map = AxisMap('axis_2_power_map', data, field_of_view, 'unit', dimension) # axis_descriptions = ['altitude', 'azimuth'] # # data = [[1, 1], [1, 1]] # bits_per_pixel = 8 # dimension = [3, 4] # format = 'raw' # field_of_view = [1, 2] # focal_depth = 1.0 # focal_depth_image = FocalDepthImage('focal_depth_image', data, bits_per_pixel, dimension, format, # field_of_view, focal_depth) # vasculature_image = RetinotopyImage('vasculature_image', np.uint16(data), bits_per_pixel, dimension, format, # field_of_view) # # return ImagingRetinotopy(sign_map, axis_1_phase_map, axis_1_power_map, axis_2_phase_map, # axis_2_power_map, axis_descriptions, focal_depth_image, # vasculature_image) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/hdf5/test_scratch.py0000644000175100001730000000701014467767506021655 0ustar00runnerdockerimport pandas as pd import numpy as np from numpy.testing import assert_array_equal from pynwb import NWBFile, NWBHDF5IO, TimeSeries from pynwb.core import ScratchData from pynwb.testing import NWBH5IOMixin, TestCase class TestScratchDataIO(NWBH5IOMixin, TestCase): def setUpContainer(self): """ Return the test ScratchData to read/write """ return ScratchData(name='foo', data=[1, 2, 3, 4], description='test scratch') def addContainer(self, nwbfile): """ Add the test ScratchData to the given NWBFile """ nwbfile.add_scratch(self.container) def getContainer(self, nwbfile): """ Return the test ScratchData from the given NWBFile """ return nwbfile.get_scratch('foo', convert=False) def roundtrip_scratch(self, data, case, **kwargs): self.filename = 'test_scratch_%s.nwb' % case description = 'a file to test writing and reading a scratch data of type %s' % case identifier = 'TEST_scratch_%s' % case nwbfile = NWBFile(session_description=description, identifier=identifier, session_start_time=self.start_time, file_create_date=self.create_date) nwbfile.add_scratch(data, name='foo', **kwargs) self.writer = NWBHDF5IO(self.filename, mode='w') self.writer.write(nwbfile) self.writer.close() self.reader = NWBHDF5IO(self.filename, mode='r') self.read_nwbfile = self.reader.read() return self.read_nwbfile.get_scratch('foo') def test_scratch_convert_int(self): data = 2 ret = self.roundtrip_scratch(data, 'int', description='test scratch') self.assertEqual(data, ret) self.validate() def test_scratch_convert_list(self): data = [1, 2, 3, 4] ret = self.roundtrip_scratch(data, 'list', description='test scratch') assert_array_equal(data, ret) self.validate() def test_scratch_convert_ndarray(self): data = np.array([1, 2, 3, 4]) ret = self.roundtrip_scratch(data, 'ndarray', description='test scratch') assert_array_equal(data, ret) self.validate() def test_scratch_convert_DataFrame_table_desc(self): """Test round trip convert of DataFrame with a table description""" data = pd.DataFrame(data={'col1': [1, 2, 3, 4], 'col2': ['a', 'b', 'c', 'd']}) self.roundtrip_scratch(data, 'DataFrame', description='my_table') ret = self.read_nwbfile.get_scratch('foo', convert=False) ret_df = ret.to_dataframe() self.assertEqual(ret.description, 'my_table') assert_array_equal(data.values, ret_df.values) assert_array_equal(data.index.values, ret_df.index.values) self.validate() def test_scratch_container(self): data = TimeSeries( name='test_ts', data=[1, 2, 3, 4, 5], unit='unit', timestamps=[1.1, 1.2, 1.3, 1.4, 1.5] ) nwbfile = NWBFile( session_description='test', identifier='test', session_start_time=self.start_time, file_create_date=self.create_date ) nwbfile.add_scratch(data) self.writer = NWBHDF5IO(self.filename, mode='w') self.writer.write(nwbfile) self.writer.close() self.reader = NWBHDF5IO(self.filename, mode='r') self.read_nwbfile = self.reader.read() ret = self.read_nwbfile.get_scratch('test_ts') self.assertContainerEqual(data, ret) self.validate() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5540276 pynwb-2.5.0/tests/integration/ros3/0000755000175100001730000000000014467767767016670 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/ros3/__init__.py0000644000175100001730000000000014467767506020756 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/ros3/test_ros3.py0000644000175100001730000000633514467767506021165 0ustar00runnerdockerfrom pynwb import NWBHDF5IO from pynwb import validate from pynwb.validate import _get_cached_namespaces_to_validate from pynwb.testing import TestCase import urllib.request import h5py class TestRos3Streaming(TestCase): """ Test file access using the HDF5 ros3 driver. This test module requires h5py to be built with the ROS3 driver: conda install -c conda-forge h5py """ @classmethod def setUpClass(cls): # this is the NWB Test Data dandiset #000126 sub-1/sub-1.nwb cls.s3_test_path = "https://dandiarchive.s3.amazonaws.com/blobs/11e/c89/11ec8933-1456-4942-922b-94e5878bb991" def setUp(self): # Skip ROS3 tests if internet is not available or the ROS3 driver is not installed try: urllib.request.urlopen('https://dandiarchive.s3.amazonaws.com/ros3test.nwb', timeout=1) except urllib.request.URLError: self.skipTest("Internet access to DANDI failed. Skipping all Ros3 streaming tests.") if 'ros3' not in h5py.registered_drivers(): self.skipTest("ROS3 driver not installed. Skipping all Ros3 streaming tests.") def test_read(self): s3_path = 'https://dandiarchive.s3.amazonaws.com/ros3test.nwb' with NWBHDF5IO(s3_path, mode='r', driver='ros3') as io: nwbfile = io.read() test_data = nwbfile.acquisition['ts_name'].data[:] self.assertEqual(len(test_data), 3) def test_dandi_read(self): with NWBHDF5IO(path=self.s3_test_path, mode='r', driver='ros3') as io: nwbfile = io.read() test_data = nwbfile.acquisition['TestData'].data[:] self.assertEqual(len(test_data), 3) def test_dandi_get_cached_namespaces(self): expected_namespaces = ["core"] expected_namespace_dependencies = { 'core': { 'hdmf-common': ( 'AlignedDynamicTable', 'CSRMatrix', 'Container', 'Data', 'DynamicTable', 'DynamicTableRegion', 'ElementIdentifiers', 'SimpleMultiContainer', 'VectorData', 'VectorIndex' ) }, 'hdmf-common': {}, 'hdmf-experimental': { 'hdmf-common': ( 'AlignedDynamicTable', 'CSRMatrix', 'Container', 'Data', 'DynamicTable', 'DynamicTableRegion', 'ElementIdentifiers', 'SimpleMultiContainer', 'VectorData', 'VectorIndex' ) } } found_namespaces, _, found_namespace_dependencies = _get_cached_namespaces_to_validate( path=self.s3_test_path, driver="ros3" ) self.assertCountEqual(first=found_namespaces, second=expected_namespaces) self.assertDictEqual(d1=expected_namespace_dependencies, d2=expected_namespace_dependencies) def test_dandi_validate(self): result, status = validate(paths=[self.s3_test_path], driver="ros3") assert result == [] assert status == 0 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5540276 pynwb-2.5.0/tests/integration/utils/0000755000175100001730000000000014467767767017142 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/utils/__init__.py0000644000175100001730000000000014467767506021230 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/integration/utils/test_io_utils.py0000644000175100001730000000466114467767506022400 0ustar00runnerdocker"""Tests related to pynwb.io.utils.""" import pytest from hdmf.build import GroupBuilder from pynwb.io.utils import get_nwb_version from pynwb.testing import TestCase class TestGetNWBVersion(TestCase): def test_get_nwb_version(self): """Get the NWB version from a builder.""" builder1 = GroupBuilder(name="root") builder1.set_attribute(name="nwb_version", value="2.0.0") builder2 = GroupBuilder(name="another") builder1.set_group(builder2) assert get_nwb_version(builder1) == (2, 0, 0) assert get_nwb_version(builder2) == (2, 0, 0) def test_get_nwb_version_missing(self): """Get the NWB version from a builder where the root builder does not have an nwb_version attribute.""" builder1 = GroupBuilder(name="root") builder2 = GroupBuilder(name="another") builder1.set_group(builder2) with pytest.raises(ValueError, match="'nwb_version' attribute is missing from the root of the NWB file."): get_nwb_version(builder1) with pytest.raises(ValueError, match="'nwb_version' attribute is missing from the root of the NWB file."): get_nwb_version(builder1) def test_get_nwb_version_prerelease_false(self): """Get the NWB version from a builder.""" builder1 = GroupBuilder(name="root") builder1.set_attribute(name="nwb_version", value="2.0.0-alpha") assert get_nwb_version(builder1) == (2, 0, 0) def test_get_nwb_version_prerelease_true1(self): """Get the NWB version from a builder.""" builder1 = GroupBuilder(name="root") builder1.set_attribute(name="nwb_version", value="2.0.0-alpha") assert get_nwb_version(builder1, include_prerelease=True) == (2, 0, 0, "alpha") def test_get_nwb_version_prerelease_true2(self): """Get the NWB version from a builder.""" builder1 = GroupBuilder(name="root") builder1.set_attribute(name="nwb_version", value="2.0.0-alpha.sha-test.5114f85") assert get_nwb_version(builder1, include_prerelease=True) == (2, 0, 0, "alpha.sha-test.5114f85") def test_get_nwb_version_20b(self): """Get the NWB version from a builder where version == "2.0b".""" builder1 = GroupBuilder(name="root") builder1.set_attribute(name="nwb_version", value="2.0b") assert get_nwb_version(builder1) == (2, 0, 0) assert get_nwb_version(builder1, include_prerelease=True) == (2, 0, 0, "b") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5580275 pynwb-2.5.0/tests/read_dandi/0000755000175100001730000000000014467767767015531 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/read_dandi/__init__.py0000644000175100001730000000000014467767506017617 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/read_dandi/test_read_dandi.py0000644000175100001730000000350314467767506021204 0ustar00runnerdockerfrom dandi.dandiapi import DandiAPIClient import sys import traceback from pynwb import NWBHDF5IO from pynwb.testing import TestCase class TestReadNWBDandisets(TestCase): """Test reading NWB files from the DANDI Archive using ROS3.""" def test_read_first_nwb_asset(self): """Test reading the first NWB asset from each dandiset that uses NWB.""" client = DandiAPIClient() dandisets = client.get_dandisets() failed_reads = dict() for i, dandiset in enumerate(dandisets): dandiset_metadata = dandiset.get_raw_metadata() # skip any dandisets that do not use NWB if not any( data_standard["identifier"] == "RRID:SCR_015242" # this is the RRID for NWB for data_standard in dandiset_metadata["assetsSummary"].get("dataStandard", []) ): continue dandiset_identifier = dandiset_metadata["identifier"] print("--------------") print(f"{i}: {dandiset_identifier}") # iterate through assets until we get an NWB file (it could be MP4) assets = dandiset.get_assets() first_asset = next(assets) while first_asset.path.split(".")[-1] != "nwb": first_asset = next(assets) if first_asset.path.split(".")[-1] != "nwb": print("No NWB files?!") continue s3_url = first_asset.get_content_url(follow_redirects=1, strip_query=True) try: with NWBHDF5IO(path=s3_url, load_namespaces=True, driver="ros3") as io: io.read() except Exception as e: print(traceback.format_exc()) failed_reads[dandiset] = e if failed_reads: print(failed_reads) sys.exit(1) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5580275 pynwb-2.5.0/tests/unit/0000755000175100001730000000000014467767767014436 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/__init__.py0000644000175100001730000000000014467767506016524 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_base.py0000644000175100001730000007640414467767506016763 0ustar00runnerdockerimport numpy as np from numpy.testing import assert_array_equal from pynwb.base import ( ProcessingModule, TimeSeries, Images, Image, TimeSeriesReferenceVectorData, TimeSeriesReference, ImageReferences ) from pynwb.testing import TestCase from pynwb.testing.mock.base import mock_TimeSeries from hdmf.data_utils import DataChunkIterator from hdmf.backends.hdf5 import H5DataIO class TestProcessingModule(TestCase): def setUp(self): self.pm = ProcessingModule( name="test_procmod", description="a test processing module" ) def _create_time_series(self): ts = TimeSeries( name="test_ts", data=[0, 1, 2, 3, 4, 5], unit="grams", timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5], ) return ts def test_init(self): """Test creating a ProcessingModule.""" self.assertEqual(self.pm.name, "test_procmod") self.assertEqual(self.pm.description, "a test processing module") def test_add_data_interface(self): """Test adding a data interface to a ProcessingModule using add(...) and retrieving it.""" ts = self._create_time_series() self.pm.add(ts) self.assertIn(ts.name, self.pm.containers) self.assertIs(ts, self.pm.containers[ts.name]) def test_deprecated_add_data_interface(self): ts = self._create_time_series() with self.assertWarnsWith( PendingDeprecationWarning, "add_data_interface will be replaced by add" ): self.pm.add_data_interface(ts) self.assertIn(ts.name, self.pm.containers) self.assertIs(ts, self.pm.containers[ts.name]) def test_deprecated_add_container(self): ts = self._create_time_series() with self.assertWarnsWith( PendingDeprecationWarning, "add_container will be replaced by add" ): self.pm.add_container(ts) self.assertIn(ts.name, self.pm.containers) self.assertIs(ts, self.pm.containers[ts.name]) def test_get_data_interface(self): """Test adding a data interface to a ProcessingModule and retrieving it using get(...).""" ts = self._create_time_series() self.pm.add(ts) tmp = self.pm.get("test_ts") self.assertIs(tmp, ts) self.assertIs(self.pm["test_ts"], self.pm.get("test_ts")) def test_deprecated_get_data_interface(self): ts = self._create_time_series() self.pm.add(ts) with self.assertWarnsWith( PendingDeprecationWarning, "get_data_interface will be replaced by get" ): tmp = self.pm.get_data_interface("test_ts") self.assertIs(tmp, ts) def test_deprecated_get_container(self): ts = self._create_time_series() self.pm.add(ts) with self.assertWarnsWith( PendingDeprecationWarning, "get_container will be replaced by get" ): tmp = self.pm.get_container("test_ts") self.assertIs(tmp, ts) def test_getitem(self): """Test adding a data interface to a ProcessingModule and retrieving it using __getitem__(...).""" ts = self._create_time_series() self.pm.add(ts) tmp = self.pm["test_ts"] self.assertIs(tmp, ts) class TestTimeSeries(TestCase): def test_init_no_parent(self): """Test creating an empty TimeSeries and that it has no parent.""" ts = TimeSeries(name="test_ts", data=list(), unit="unit", timestamps=list()) self.assertEqual(ts.name, "test_ts") self.assertIsNone(ts.parent) def test_init_datalink_set(self): """Test creating a TimeSeries and that data_link is an empty set.""" ts = TimeSeries(name="test_ts", data=list(), unit="unit", timestamps=list()) self.assertIsInstance(ts.data_link, set) self.assertEqual(len(ts.data_link), 0) def test_init_timestampslink_set(self): """Test creating a TimeSeries and that timestamps_link is an empty set.""" ts = TimeSeries(name="test_ts", data=list(), unit="unit", timestamps=list()) self.assertIsInstance(ts.timestamp_link, set) self.assertEqual(len(ts.timestamp_link), 0) def test_init_data_timestamps(self): data = [0, 1, 2, 3, 4] timestamps = [0.0, 0.1, 0.2, 0.3, 0.4] ts = TimeSeries(name="test_ts", data=data, unit="volts", timestamps=timestamps) self.assertIs(ts.data, data) self.assertIs(ts.timestamps, timestamps) self.assertEqual(ts.conversion, 1.0) self.assertEqual(ts.offset, 0.0) self.assertEqual(ts.resolution, -1.0) self.assertEqual(ts.unit, "volts") self.assertEqual(ts.interval, 1) self.assertEqual(ts.time_unit, "seconds") self.assertEqual(ts.num_samples, 5) self.assertIsNone(ts.continuity) self.assertIsNone(ts.rate) self.assertIsNone(ts.starting_time) def test_init_conversion_offset(self): data = [0, 1, 2, 3, 4] timestamps = [0.0, 0.1, 0.2, 0.3, 0.4] conversion = 2.1 offset = 1.2 ts = TimeSeries( name="test_ts", data=data, unit="volts", timestamps=timestamps, conversion=conversion, offset=offset, ) self.assertIs(ts.data, data) self.assertEqual(ts.conversion, conversion) self.assertEqual(ts.offset, offset) def test_no_time(self): with self.assertRaisesWith( TypeError, "either 'timestamps' or 'rate' must be specified" ): TimeSeries(name="test_ts2", data=[10, 11, 12, 13, 14, 15], unit="grams") def test_no_starting_time(self): """Test that if no starting_time is given, 0.0 is assumed.""" ts1 = TimeSeries(name="test_ts1", data=[1, 2, 3], unit="unit", rate=0.1) self.assertEqual(ts1.starting_time, 0.0) def test_init_rate(self): ts = TimeSeries( name="test_ts", data=list(), unit="volts", starting_time=1.0, rate=2.0, ) self.assertEqual(ts.starting_time, 1.0) self.assertEqual(ts.starting_time_unit, "seconds") self.assertEqual(ts.rate, 2.0) self.assertEqual(ts.time_unit, "seconds") self.assertIsNone(ts.timestamps) def test_data_timeseries(self): """Test that setting a TimeSeries.data to another TimeSeries links the data correctly.""" data = [0, 1, 2, 3] timestamps1 = [0.0, 0.1, 0.2, 0.3] timestamps2 = [1.0, 1.1, 1.2, 1.3] ts1 = TimeSeries( name="test_ts1", data=data, unit="grams", timestamps=timestamps1 ) ts2 = TimeSeries( name="test_ts2", data=ts1, unit="grams", timestamps=timestamps2 ) self.assertEqual(ts2.data, data) self.assertEqual(ts1.num_samples, ts2.num_samples) self.assertEqual(ts1.data_link, set([ts2])) def test_timestamps_timeseries(self): """Test that setting a TimeSeries.timestamps to another TimeSeries links the timestamps correctly.""" data1 = [0, 1, 2, 3] data2 = [10, 11, 12, 13] timestamps = [0.0, 0.1, 0.2, 0.3] ts1 = TimeSeries( name="test_ts1", data=data1, unit="grams", timestamps=timestamps ) ts2 = TimeSeries(name="test_ts2", data=data2, unit="grams", timestamps=ts1) self.assertEqual(ts2.timestamps, timestamps) self.assertEqual(ts1.timestamp_link, set([ts2])) def test_good_continuity_timeseries(self): ts = TimeSeries( name="test_ts1", data=[0, 1, 2, 3, 4, 5], unit="grams", timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5], continuity="continuous", ) self.assertEqual(ts.continuity, "continuous") def test_bad_continuity_timeseries(self): msg = ( "TimeSeries.__init__: forbidden value for 'continuity' (got 'wrong', " "expected ['continuous', 'instantaneous', 'step'])" ) with self.assertRaisesWith(ValueError, msg): TimeSeries( name="test_ts1", data=[0, 1, 2, 3, 4, 5], unit="grams", timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5], continuity="wrong", ) def _create_time_series_with_data(self, data): ts = TimeSeries(name="test_ts1", data=data, unit="grams", rate=0.1) return ts def test_dataio_list_data(self): length = 100 data = list(range(length)) ts = self._create_time_series_with_data(data) self.assertEqual(ts.num_samples, length) assert data == list(ts.data) def test_dataio_dci_data(self): def generator_factory(): return (i for i in range(100)) data = H5DataIO(DataChunkIterator(data=generator_factory())) ts = self._create_time_series_with_data(data) with self.assertWarnsWith( UserWarning, "The data attribute on this TimeSeries (named: test_ts1) has a " "__len__, but it cannot be read", ): self.assertIsNone(ts.num_samples) for xi, yi in zip(data, generator_factory()): assert np.allclose(xi, yi) def test_dci_data(self): def generator_factory(): return (i for i in range(100)) data = DataChunkIterator(data=generator_factory()) ts = self._create_time_series_with_data(data) with self.assertWarnsWith( UserWarning, "The data attribute on this TimeSeries (named: test_ts1) has no __len__", ): self.assertIsNone(ts.num_samples) for xi, yi in zip(data, generator_factory()): assert np.allclose(xi, yi) def test_dci_data_arr(self): def generator_factory(): return (np.array([i, i + 1]) for i in range(100)) data = DataChunkIterator(data=generator_factory()) ts = self._create_time_series_with_data(data) with self.assertWarnsWith( UserWarning, "The data attribute on this TimeSeries (named: test_ts1) has no __len__", ): self.assertIsNone(ts.num_samples) for xi, yi in zip(data, generator_factory()): assert np.allclose(xi, yi) def test_dataio_list_timestamps(self): length = 100 data = list(range(length)) ts = self._create_time_series_with_data(data) self.assertEqual(ts.num_samples, length) assert data == list(ts.data) def _create_time_series_with_timestamps(self, timestamps): # data has no __len__ for these tests def generator_factory(): return (i for i in range(100)) ts = TimeSeries( name="test_ts1", data=DataChunkIterator(data=generator_factory()), unit="grams", timestamps=timestamps, ) return ts def test_dataio_dci_timestamps(self): def generator_factory(): return (i for i in range(100)) timestamps = H5DataIO(DataChunkIterator(data=generator_factory())) ts = self._create_time_series_with_timestamps(timestamps) with self.assertWarns(UserWarning) as record: self.assertIsNone(ts.num_samples) assert len(record.warnings) == 2 assert record.warnings[0].message.args[0] == ( "The data attribute on this TimeSeries (named: test_ts1) has no __len__" ) assert record.warnings[1].message.args[0] == ( "The timestamps attribute on this TimeSeries (named: test_ts1) has a " "__len__, but it cannot be read" ) for xi, yi in zip(timestamps, generator_factory()): assert np.allclose(xi, yi) def test_dci_timestamps(self): def generator_factory(): return (i for i in range(100)) timestamps = DataChunkIterator(data=generator_factory()) ts = self._create_time_series_with_timestamps(timestamps) with self.assertWarns(UserWarning) as record: self.assertIsNone(ts.num_samples) assert len(record.warnings) == 2 assert record.warnings[0].message.args[0] == ( "The data attribute on this TimeSeries (named: test_ts1) has no __len__" ) assert record.warnings[1].message.args[0] == ( "The timestamps attribute on this TimeSeries (named: test_ts1) has no __len__" ) for xi, yi in zip(timestamps, generator_factory()): assert np.allclose(xi, yi) def test_dci_timestamps_arr(self): def generator_factory(): return np.array(np.arange(100)) timestamps = DataChunkIterator(data=generator_factory()) ts = self._create_time_series_with_timestamps(timestamps) with self.assertWarns(UserWarning) as record: self.assertIsNone(ts.num_samples) assert len(record.warnings) == 2 assert record.warnings[0].message.args[0] == ( "The data attribute on this TimeSeries (named: test_ts1) has no __len__" ) assert record.warnings[1].message.args[0] == ( "The timestamps attribute on this TimeSeries (named: test_ts1) has no __len__" ) for xi, yi in zip(timestamps, generator_factory()): assert np.allclose(xi, yi) def test_conflicting_time_args(self): with self.assertRaisesWith( ValueError, "Specifying rate and timestamps is not supported." ): TimeSeries( name="test_ts2", data=[10, 11, 12], unit="grams", rate=30.0, timestamps=[0.3, 0.4, 0.5], ) with self.assertRaisesWith( ValueError, "Specifying starting_time and timestamps is not supported." ): TimeSeries( name="test_ts2", data=[10, 11, 12], unit="grams", starting_time=30.0, timestamps=[0.3, 0.4, 0.5], ) def test_dimension_warning(self): msg = ( "TimeSeries 'test_ts2': Length of data does not match length of timestamps. Your data may be " "transposed. Time should be on the 0th dimension" ) with self.assertWarnsWith(UserWarning, msg): TimeSeries( name="test_ts2", data=[10, 11, 12], unit="grams", timestamps=[0.3, 0.4, 0.5, 0.6, 0.7, 0.8], ) def test_get_timestamps(self): time_series = mock_TimeSeries(data=[1, 2, 3], rate=40.0, starting_time=30.0) assert_array_equal(time_series.get_timestamps(), [30, 30+1/40, 30+2/40]) time_series = mock_TimeSeries(data=[1, 2, 3], timestamps=[3, 4, 5], rate=None) assert_array_equal(time_series.get_timestamps(), [3, 4, 5]) def test_get_data_in_units(self): ts = mock_TimeSeries(data=[1., 2., 3.], conversion=2., offset=3.) assert_array_equal(ts.get_data_in_units(), [5., 7., 9.]) ts = mock_TimeSeries(data=[1., 2., 3.], conversion=2.) assert_array_equal(ts.get_data_in_units(), [2., 4., 6.]) ts = mock_TimeSeries(data=[1., 2., 3.]) assert_array_equal(ts.get_data_in_units(), [1., 2., 3.]) class TestImage(TestCase): def test_init(self): im = Image(name="test_image", data=np.ones((10, 10))) assert im.name == "test_image" assert np.all(im.data == np.ones((10, 10))) class TestImages(TestCase): def test_images(self): image1 = Image(name='test_image1', data=np.ones((10, 10))) image2 = Image(name='test_image2', data=np.ones((10, 10))) image_references = ImageReferences(name='order_of_images', data=[image2, image1]) images = Images(name='images_name', images=[image1, image2], order_of_images=image_references) assert images.name == "images_name" assert images.images == dict(test_image1=image1, test_image2=image2) self.assertIs(images.order_of_images[0], image2) self.assertIs(images.order_of_images[1], image1) class TestTimeSeriesReferenceVectorData(TestCase): def _create_time_series_with_rate(self): ts = TimeSeries( name="test", description="test", data=np.arange(10), unit="unit", starting_time=5.0, rate=0.1, ) return ts def _create_time_series_with_timestamps(self): ts = TimeSeries( name="test", description="test", data=np.arange(10), unit="unit", timestamps=np.arange(10.0), ) return ts def test_init(self): temp = TimeSeriesReferenceVectorData() self.assertEqual(temp.name, "timeseries") self.assertEqual( temp.description, "Column storing references to a TimeSeries (rows). For each TimeSeries this " "VectorData column stores the start_index and count to indicate the range in time " "to be selected as well as an object reference to the TimeSeries.", ) self.assertListEqual(temp.data, []) temp = TimeSeriesReferenceVectorData(name="test", description="test") self.assertEqual(temp.name, "test") self.assertEqual(temp.description, "test") def test_get_empty(self): """Get data from an empty TimeSeriesReferenceVectorData""" temp = TimeSeriesReferenceVectorData() self.assertListEqual(temp[:], []) with self.assertRaises(IndexError): temp[0] def test_append_get_length1_valid_data(self): """Get data from a TimeSeriesReferenceVectorData with one element and valid data""" temp = TimeSeriesReferenceVectorData() value = TimeSeriesReference(0, 5, self._create_time_series_with_rate()) temp.append(value) self.assertTupleEqual(temp[0], value) self.assertListEqual( temp[:], [ TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE(*value), ], ) def test_add_row_get_length1_valid_data(self): """Get data from a TimeSeriesReferenceVectorData with one element and valid data""" temp = TimeSeriesReferenceVectorData() value = TimeSeriesReference(0, 5, self._create_time_series_with_rate()) temp.add_row(value) self.assertTupleEqual(temp[0], value) self.assertListEqual( temp[:], [ TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE(*value), ], ) def test_get_length1_invalid_data(self): """Get data from a TimeSeriesReferenceVectorData with one element and invalid data""" temp = TimeSeriesReferenceVectorData() value = TimeSeriesReference(-1, -1, self._create_time_series_with_rate()) temp.append(value) # test index slicing re = temp[0] self.assertTrue( isinstance(re, TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE) ) self.assertTupleEqual( re, TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_NONE_TYPE ) # test array slicing and list slicing selection = [ slice(None), [ 0, ], ] for s in selection: re = temp[s] self.assertTrue(isinstance(re, list)) self.assertTrue(len(re), 1) self.assertTrue( isinstance( re[0], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE ) ) self.assertTupleEqual( re[0], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_NONE_TYPE ) def test_get_length5_valid_data(self): """Get data from a TimeSeriesReferenceVectorData with 5 elements""" temp = TimeSeriesReferenceVectorData() num_values = 5 values = [ TimeSeriesReference(0, 5, self._create_time_series_with_rate()) for i in range(num_values) ] for v in values: temp.append(v) # Test single element selection for i in range(num_values): # test index slicing re = temp[i] self.assertTupleEqual(re, values[i]) # test slicing re = temp[i : i + 1] self.assertTupleEqual( re[0], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE(*values[i]), ) # Test multi element selection re = temp[0:2] self.assertTupleEqual( re[0], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE(*values[0]) ) self.assertTupleEqual( re[1], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE(*values[1]) ) def test_get_length5_with_invalid_data(self): """Get data from a TimeSeriesReferenceVectorData with 5 elements""" temp = TimeSeriesReferenceVectorData() num_values = 5 values = [ TimeSeriesReference(0, 5, self._create_time_series_with_rate()) for i in range(num_values - 2) ] values = ( [ TimeSeriesReference(-1, -1, self._create_time_series_with_rate()), ] + values + [ TimeSeriesReference(-1, -1, self._create_time_series_with_rate()), ] ) for v in values: temp.append(v) # Test single element selection for i in range(num_values): # test index slicing re = temp[i] if i in [0, 4]: self.assertTrue( isinstance( re, TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE ) ) self.assertTupleEqual( re, TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_NONE_TYPE ) else: self.assertTupleEqual(re, values[i]) # test slicing re = temp[i : i + 1] if i in [0, 4]: self.assertTrue( isinstance( re[0], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE ) ) self.assertTupleEqual( re[0], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_NONE_TYPE ) else: self.assertTupleEqual( re[0], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE( *values[i] ), ) # Test multi element selection re = temp[0:2] self.assertTupleEqual( re[0], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_NONE_TYPE ) self.assertTupleEqual( re[1], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE(*values[1]) ) def test_add_row(self): v = TimeSeriesReferenceVectorData(name='a', description='a') val = TimeSeriesReference(0, 5, TimeSeries(name='test', description='test', data=np.arange(10), unit='unit', starting_time=5.0, rate=0.1)) v.add_row(val) self.assertTupleEqual(v[0], val) def test_add_row_with_plain_tuple(self): v = TimeSeriesReferenceVectorData(name='a', description='a') val = (0, 5, TimeSeries(name='test', description='test', data=np.arange(10), unit='unit', starting_time=5.0, rate=0.1)) v.add_row(val) self.assertTupleEqual(v[0], val) def test_add_row_with_bad_tuple(self): v = TimeSeriesReferenceVectorData(name='a', description='a') val = (0.0, 5, TimeSeries(name='test', description='test', data=np.arange(10), unit='unit', starting_time=5.0, rate=0.1)) with self.assertRaisesWith(TypeError, "idx_start must be an integer not "): v.add_row(val) def test_add_row_restricted_type(self): v = TimeSeriesReferenceVectorData(name="a", description="a") with self.assertRaisesWith( TypeError, "TimeSeriesReferenceVectorData.add_row: incorrect type for " "'val' (got 'int', expected 'TimeSeriesReference or tuple')", ): v.add_row(1) def test_append(self): v = TimeSeriesReferenceVectorData(name='a', description='a') val = TimeSeriesReference(0, 5, TimeSeries(name='test', description='test', data=np.arange(10), unit='unit', starting_time=5.0, rate=0.1)) v.append(val) self.assertTupleEqual(v[0], val) def test_append_with_plain_tuple(self): v = TimeSeriesReferenceVectorData(name='a', description='a') val = (0, 5, TimeSeries(name='test', description='test', data=np.arange(10), unit='unit', starting_time=5.0, rate=0.1)) v.append(val) self.assertTupleEqual(v[0], val) def test_append_with_bad_tuple(self): v = TimeSeriesReferenceVectorData(name='a', description='a') val = (0.0, 5, TimeSeries(name='test', description='test', data=np.arange(10), unit='unit', starting_time=5.0, rate=0.1)) with self.assertRaisesWith(TypeError, "idx_start must be an integer not "): v.append(val) def test_append_restricted_type(self): v = TimeSeriesReferenceVectorData(name="a", description="a") with self.assertRaisesWith( TypeError, "TimeSeriesReferenceVectorData.append: incorrect type for " "'arg' (got 'float', expected 'TimeSeriesReference or tuple')", ): v.append(2.0) class TestTimeSeriesReference(TestCase): def _create_time_series_with_rate(self): ts = TimeSeries( name="test", description="test", data=np.arange(10), unit="unit", starting_time=5.0, rate=0.1, ) return ts def _create_time_series_with_timestamps(self): ts = TimeSeries( name="test", description="test", data=np.arange(10), unit="unit", timestamps=np.arange(10.0), ) return ts def test_check_types(self): # invalid selection but with correct types tsr = TimeSeriesReference(-1, -1, self._create_time_series_with_rate()) self.assertTrue(tsr.check_types()) # invalid types, use float instead of int for both idx_start and count tsr = TimeSeriesReference(1.0, 5.0, self._create_time_series_with_rate()) with self.assertRaisesWith( TypeError, "idx_start must be an integer not " ): tsr.check_types() # invalid types, use float instead of int for idx_start only tsr = TimeSeriesReference(1.0, 5, self._create_time_series_with_rate()) with self.assertRaisesWith( TypeError, "idx_start must be an integer not " ): tsr.check_types() # invalid types, use float instead of int for count only tsr = TimeSeriesReference(1, 5.0, self._create_time_series_with_rate()) with self.assertRaisesWith( TypeError, "count must be an integer " ): tsr.check_types() # invalid type for TimeSeries but valid idx_start and count tsr = TimeSeriesReference(1, 5, None) with self.assertRaisesWith( TypeError, "timeseries must be of type TimeSeries. " ): tsr.check_types() def test_is_invalid(self): tsr = TimeSeriesReference(-1, -1, self._create_time_series_with_rate()) self.assertFalse(tsr.isvalid()) def test_is_valid(self): tsr = TimeSeriesReference(0, 10, self._create_time_series_with_rate()) self.assertTrue(tsr.isvalid()) def test_is_valid_bad_index(self): # Error: negative start_index but positive count tsr = TimeSeriesReference(-1, 10, self._create_time_series_with_rate()) with self.assertRaisesWith( IndexError, "'idx_start' -1 out of range for timeseries 'test'" ): tsr.isvalid() # Error: start_index too large tsr = TimeSeriesReference(10, 0, self._create_time_series_with_rate()) with self.assertRaisesWith( IndexError, "'idx_start' 10 out of range for timeseries 'test'" ): tsr.isvalid() # Error: positive start_index but negative count tsr = TimeSeriesReference(0, -3, self._create_time_series_with_rate()) with self.assertRaisesWith( IndexError, "'count' -3 invalid. 'count' must be positive" ): tsr.isvalid() # Error: start_index + count too large tsr = TimeSeriesReference(3, 10, self._create_time_series_with_rate()) with self.assertRaisesWith( IndexError, "'idx_start + count' out of range for timeseries 'test'" ): tsr.isvalid() def test_is_valid_no_num_samples(self): def generator_factory(): return (i for i in range(100)) data = DataChunkIterator(data=generator_factory()) ts = TimeSeries(name="test_ts1", data=data, unit="grams", rate=0.1) tsr = TimeSeriesReference(0, 10, ts) with self.assertWarnsWith( UserWarning, "The data attribute on this TimeSeries (named: test_ts1) has no __len__", ): self.assertTrue(tsr.isvalid()) def test_timestamps_property(self): # Timestamps from starting_time and rate tsr = TimeSeriesReference(5, 4, self._create_time_series_with_rate()) np.testing.assert_array_equal(tsr.timestamps, np.array([5.5, 5.6, 5.7, 5.8])) # Timestamps from timestamps directly tsr = TimeSeriesReference(5, 4, self._create_time_series_with_timestamps()) np.testing.assert_array_equal(tsr.timestamps, np.array([5.0, 6.0, 7.0, 8.0])) def test_timestamps_property_invalid_reference(self): # Timestamps from starting_time and rate tsr = TimeSeriesReference(-1, -1, self._create_time_series_with_rate()) self.assertIsNone(tsr.timestamps) def test_timestamps_property_bad_reference(self): tsr = TimeSeriesReference(0, 12, self._create_time_series_with_timestamps()) with self.assertRaisesWith( IndexError, "'idx_start + count' out of range for timeseries 'test'" ): tsr.timestamps tsr = TimeSeriesReference(0, 12, self._create_time_series_with_rate()) with self.assertRaisesWith( IndexError, "'idx_start + count' out of range for timeseries 'test'" ): tsr.timestamps def test_data_property(self): tsr = TimeSeriesReference(5, 4, self._create_time_series_with_rate()) np.testing.assert_array_equal(tsr.data, np.array([5.0, 6.0, 7.0, 8.0])) def test_data_property_invalid_reference(self): tsr = TimeSeriesReference(-1, -1, self._create_time_series_with_rate()) self.assertIsNone(tsr.data) def test_data_property_bad_reference(self): tsr = TimeSeriesReference(0, 12, self._create_time_series_with_rate()) with self.assertRaisesWith( IndexError, "'idx_start + count' out of range for timeseries 'test'" ): tsr.data ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_behavior.py0000644000175100001730000000675514467767506017652 0ustar00runnerdockerimport numpy as np from pynwb import TimeSeries from pynwb.misc import IntervalSeries from pynwb.behavior import (SpatialSeries, BehavioralEpochs, BehavioralEvents, BehavioralTimeSeries, PupilTracking, EyeTracking, CompassDirection, Position) from pynwb.testing import TestCase class SpatialSeriesConstructor(TestCase): def test_init(self): sS = SpatialSeries( name='test_sS', data=np.ones((3, 2)), reference_frame='reference_frame', timestamps=[1., 2., 3.] ) self.assertEqual(sS.name, 'test_sS') self.assertEqual(sS.unit, 'meters') self.assertEqual(sS.reference_frame, 'reference_frame') def test_set_unit(self): sS = SpatialSeries( name='test_sS', data=np.ones((3, 2)), reference_frame='reference_frame', unit='degrees', timestamps=[1., 2., 3.] ) self.assertEqual(sS.unit, 'degrees') def test_gt_3_cols(self): msg = ("SpatialSeries 'test_sS' has data shape (5, 4) which is not compliant with NWB 2.5 and greater. " "The second dimension should have length <= 3 to represent at most x, y, z.") with self.assertWarnsWith(UserWarning, msg): SpatialSeries( name="test_sS", data=np.ones((5, 4)), reference_frame="reference_frame", rate=30. ) class BehavioralEpochsConstructor(TestCase): def test_init(self): data = [0, 1, 0] iS = IntervalSeries(name='test_iS', data=data, timestamps=[1., 2., 3.]) bE = BehavioralEpochs(iS) self.assertEqual(bE.interval_series['test_iS'], iS) class BehavioralEventsConstructor(TestCase): def test_init(self): ts = TimeSeries(name='test_ts', data=np.ones((3, 2)), unit='unit', timestamps=[1., 2., 3.]) bE = BehavioralEvents(ts) self.assertEqual(bE.time_series['test_ts'], ts) class BehavioralTimeSeriesConstructor(TestCase): def test_init(self): ts = TimeSeries(name='test_ts', data=np.ones((3, 2)), unit='unit', timestamps=[1., 2., 3.]) bts = BehavioralTimeSeries(ts) self.assertEqual(bts.time_series['test_ts'], ts) class PupilTrackingConstructor(TestCase): def test_init(self): ts = TimeSeries(name='test_ts', data=np.ones((3, 2)), unit='unit', timestamps=[1., 2., 3.]) pt = PupilTracking(ts) self.assertEqual(pt.time_series['test_ts'], ts) class EyeTrackingConstructor(TestCase): def test_init(self): sS = SpatialSeries( name='test_sS', data=np.ones((3, 2)), reference_frame='reference_frame', timestamps=[1., 2., 3.] ) et = EyeTracking(sS) self.assertEqual(et.spatial_series['test_sS'], sS) class CompassDirectionConstructor(TestCase): def test_init(self): sS = SpatialSeries( name='test_sS', data=np.ones((3, 2)), reference_frame='reference_frame', timestamps=[1., 2., 3.] ) cd = CompassDirection(sS) self.assertEqual(cd.spatial_series['test_sS'], sS) class PositionConstructor(TestCase): def test_init(self): sS = SpatialSeries( name='test_sS', data=np.ones((3, 2)), reference_frame='reference_frame', timestamps=[1., 2., 3.] ) pc = Position(sS) self.assertEqual(pc.spatial_series.get('test_sS'), sS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_core.py0000644000175100001730000001065414467767506016774 0ustar00runnerdockerfrom datetime import datetime from dateutil.tz import tzlocal import numpy as np from hdmf.utils import docval from pynwb import NWBFile, TimeSeries, available_namespaces from pynwb.core import NWBContainer, NWBData from pynwb.testing import TestCase class MyTestClass(NWBContainer): __nwbfields__ = ("prop1", "prop2") @docval({"name": "name", "type": str, "doc": "The name of this container"}) def __init__(self, **kwargs): super().__init__(**kwargs) self.prop1 = "test1" class TestNWBContainer(TestCase): def test_constructor(self): """Test constructor """ obj = MyTestClass("obj1") self.assertEqual(obj.name, "obj1") obj.prop2 = "test2" def test_nwbfields(self): """Test that getters and setters work for nwbfields """ obj = MyTestClass("obj1") obj.prop2 = "test2" self.assertEqual(obj.prop1, "test1") self.assertEqual(obj.prop2, "test2") class MyNWBData(NWBData): __nwbfields__ = ("data", ) @docval( {"name": "name", "type": str, "doc": "The name of this container"}, {"name": "data", "type": ("array_data", "data"), "doc": "any data"}, ) def __init__(self, **kwargs): super().__init__(**kwargs) class TestNWBData(TestCase): def test_constructor(self): """Test constructor """ obj = MyNWBData("obj1", data=[[1, 2, 3], [1, 2, 3]]) self.assertEqual(obj.name, "obj1") def test_append_list(self): obj = MyNWBData("obj1", data=[[1, 2, 3], [1, 2, 3]]) obj.append([4, 5, 6]) np.testing.assert_array_equal(obj.data, [[1, 2, 3], [1, 2, 3], [4, 5, 6]]) def test_append_ndarray_2d(self): obj = MyNWBData("obj1", data=np.array([[1, 2, 3], [1, 2, 3]])) obj.append([4, 5, 6]) np.testing.assert_array_equal(obj.data, [[1, 2, 3], [1, 2, 3], [4, 5, 6]]) def test_append_ndarray_1d(self): obj = MyNWBData("obj1", data=np.array([1, 2, 3])) obj.append([4]) np.testing.assert_array_equal(obj.data, [1, 2, 3, 4]) def test_extend_list(self): obj = MyNWBData("obj1", data=[[1, 2, 3], [1, 2, 3]]) obj.extend([[4, 5, 6]]) np.testing.assert_array_equal(obj.data, [[1, 2, 3], [1, 2, 3], [4, 5, 6]]) def test_extend_ndarray_1d(self): obj = MyNWBData("obj1", data=np.array([1, 2, 3])) obj.extend([4, 5, 6]) np.testing.assert_array_equal(obj.data, [1, 2, 3, 4, 5, 6]) def test_extend_ndarray_2d(self): obj = MyNWBData("obj1", data=np.array([[1, 2, 3], [1, 2, 3]])) obj.extend([[4, 5, 6]]) np.testing.assert_array_equal(obj.data, [[1, 2, 3], [1, 2, 3], [4, 5, 6]]) class TestPrint(TestCase): def test_print_file(self): nwbfile = NWBFile( session_description="session_description", identifier="identifier", session_start_time=datetime.now(tzlocal()), ) ts1 = TimeSeries( name="name1", data=[1000, 2000, 3000], unit="unit", timestamps=[1.0, 2.0, 3.0], ) ts2 = TimeSeries( name="name2", data=[1000, 2000, 3000], unit="unit", timestamps=[1.0, 2.0, 3.0], ) expected = """name1 pynwb.base.TimeSeries at 0x%d Fields: comments: no comments conversion: 1.0 data: [1000 2000 3000] description: no description interval: 1 offset: 0.0 resolution: -1.0 timestamps: [1. 2. 3.] timestamps_unit: seconds unit: unit """ expected %= id(ts1) self.assertEqual(str(ts1), expected) nwbfile.add_acquisition(ts1) nwbfile.add_acquisition(ts2) nwbfile.add_epoch(start_time=1.0, stop_time=10.0, tags=["tag1", "tag2"]) expected_re = r"""root pynwb\.file\.NWBFile at 0x\d+ Fields: acquisition: { name1 , name2 } epoch_tags: { tag1, tag2 } epochs: epochs file_create_date: \[datetime.datetime\(.*\)\] identifier: identifier session_description: session_description session_start_time: .* timestamps_reference_time: .* """ self.assertRegex(str(nwbfile), expected_re) class TestAvailableNamespaces(TestCase): def test_available_namespaces(self): self.assertEqual( available_namespaces(), ("hdmf-common", "hdmf-experimental", "core") ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_core_NWBContainer.py0000644000175100001730000000154014467767506021337 0ustar00runnerdockerimport unittest from pynwb.core import NWBContainer from hdmf.utils import docval class MyTestClass(NWBContainer): __nwbfields__ = ('prop1', 'prop2') @docval({'name': 'name', 'type': str, 'doc': 'The name of this container'}) def __init__(self, **kwargs): super().__init__(**kwargs) self.prop1 = 'test1' class TestNWBContainer(unittest.TestCase): def test_constructor(self): """Test constructor """ obj = MyTestClass('obj1') self.assertEqual(obj.name, 'obj1') obj.prop2 = 'test2' def test_nwbfields(self): """Test that getters and setters work for nwbfields """ obj = MyTestClass('obj1') obj.prop2 = 'test2' self.assertEqual(obj.prop1, 'test1') self.assertEqual(obj.prop2, 'test2') if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_device.py0000644000175100001730000000067714467767506017307 0ustar00runnerdockerfrom pynwb.device import Device from pynwb.testing import TestCase class TestDevice(TestCase): def test_init(self): device = Device(name='device_name', description='description', manufacturer='manufacturer') self.assertEqual(device.name, 'device_name') self.assertEqual(device.description, 'description') self.assertEqual(device.manufacturer, 'manufacturer') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_ecephys.py0000644000175100001730000003353414467767506017506 0ustar00runnerdockerimport warnings import numpy as np from pynwb.ecephys import ( ElectricalSeries, SpikeEventSeries, EventDetection, Clustering, EventWaveform, ClusterWaveforms, LFP, FilteredEphys, FeatureExtraction, ElectrodeGroup, ) from pynwb.device import Device from pynwb.file import ElectrodeTable from pynwb.testing import TestCase from hdmf.common import DynamicTableRegion def make_electrode_table(): table = ElectrodeTable() dev1 = Device('dev1') group = ElectrodeGroup('tetrode1', 'tetrode description', 'tetrode location', dev1) table.add_row(location='CA1', group=group, group_name='tetrode1') table.add_row(location='CA1', group=group, group_name='tetrode1') table.add_row(location='CA1', group=group, group_name='tetrode1') table.add_row(location='CA1', group=group, group_name='tetrode1') return table class ElectricalSeriesConstructor(TestCase): def _create_table_and_region(self): table = make_electrode_table() region = DynamicTableRegion( name='electrodes', data=[0, 2], description='the first and third electrodes', table=table ) return table, region def test_init(self): data = list(range(10)) ts = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] channel_conversion = [2., 6.3] filtering = 'Low-pass filter at 300 Hz' table, region = self._create_table_and_region() eS = ElectricalSeries( name='test_eS', data=data, electrodes=region, channel_conversion=channel_conversion, filtering=filtering, timestamps=ts ) self.assertEqual(eS.name, 'test_eS') self.assertEqual(eS.data, data) self.assertEqual(eS.electrodes, region) self.assertEqual(eS.timestamps, ts) self.assertEqual(eS.channel_conversion, [2., 6.3]) self.assertEqual(eS.filtering, filtering) def test_link(self): table, region = self._create_table_and_region() ts1 = ElectricalSeries('test_ts1', [0, 1, 2, 3, 4, 5], region, timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5]) ts2 = ElectricalSeries('test_ts2', ts1, region, timestamps=ts1) ts3 = ElectricalSeries('test_ts3', ts2, region, timestamps=ts2) self.assertEqual(ts2.data, [0, 1, 2, 3, 4, 5]) self.assertEqual(ts2.timestamps, [0.0, 0.1, 0.2, 0.3, 0.4, 0.5]) self.assertEqual(ts3.data, [0, 1, 2, 3, 4, 5]) self.assertEqual(ts3.timestamps, [0.0, 0.1, 0.2, 0.3, 0.4, 0.5]) def test_invalid_data_shape(self): table, region = self._create_table_and_region() with self.assertRaisesWith(ValueError, ("ElectricalSeries.__init__: incorrect shape for 'data' (got '(2, 2, 2, " "2)', expected '((None,), (None, None), (None, None, None))')")): ElectricalSeries('test_ts1', np.ones((2, 2, 2, 2)), region, timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5]) def test_dimensions_warning(self): table, region = self._create_table_and_region() with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") ElectricalSeries( name="test_ts1", data=np.ones((6, 3)), electrodes=region, timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5] ) self.assertEqual(len(w), 1) assert ( "ElectricalSeries 'test_ts1': The second dimension of data does not match the length of electrodes. " "Your data may be transposed." ) in str(w[-1].message) with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") ElectricalSeries( name="test_ts1", data=np.ones((2, 6)), electrodes=region, rate=30000., ) self.assertEqual(len(w), 1) assert ( "ElectricalSeries 'test_ts1': The second dimension of data does not match the length of electrodes, " "but instead the first does. Data is oriented incorrectly and should be transposed." ) in str(w[-1].message) class SpikeEventSeriesConstructor(TestCase): def _create_table_and_region(self): table = make_electrode_table() region = DynamicTableRegion( name='electrodes', data=[1, 3], description='the second and fourth electrodes', table=table ) return table, region def test_init(self): table, region = self._create_table_and_region() data = ((1, 1), (2, 2), (3, 3)) timestamps = np.arange(3) sES = SpikeEventSeries(name='test_sES', data=data, timestamps=timestamps, electrodes=region) self.assertEqual(sES.name, 'test_sES') # self.assertListEqual(sES.data, data) np.testing.assert_array_equal(sES.data, data) np.testing.assert_array_equal(sES.timestamps, timestamps) def test_no_rate(self): table, region = self._create_table_and_region() data = ((1, 1, 1), (2, 2, 2)) with self.assertRaises(TypeError): SpikeEventSeries(name='test_sES', data=data, electrodes=region, rate=1.) def test_incorrect_timestamps(self): table, region = self._create_table_and_region() data = ((1, 1, 1), (2, 2, 2)) with self.assertRaisesWith(ValueError, "Must provide the same number of timestamps and spike events"): SpikeEventSeries(name='test_sES', data=data, electrodes=region, timestamps=[1.0, 2.0, 3.0]) class ElectrodeGroupConstructor(TestCase): def test_init(self): dev1 = Device('dev1') group = ElectrodeGroup('elec1', 'electrode description', 'electrode location', dev1, (1, 2, 3)) self.assertEqual(group.name, 'elec1') self.assertEqual(group.description, 'electrode description') self.assertEqual(group.location, 'electrode location') self.assertEqual(group.device, dev1) self.assertEqual(group.position, (1, 2, 3)) def test_init_position_none(self): dev1 = Device('dev1') group = ElectrodeGroup('elec1', 'electrode description', 'electrode location', dev1) self.assertEqual(group.name, 'elec1') self.assertEqual(group.description, 'electrode description') self.assertEqual(group.location, 'electrode location') self.assertEqual(group.device, dev1) self.assertIsNone(group.position) def test_init_position_bad(self): dev1 = Device('dev1') with self.assertRaises(ValueError): ElectrodeGroup('elec1', 'electrode description', 'electrode location', dev1, (1, 2)) class EventDetectionConstructor(TestCase): def _create_table_and_region(self): table = make_electrode_table() region = DynamicTableRegion( name='electrodes', data=[0, 2], description='the first and third electrodes', table=table ) return table, region def test_init(self): data = list(range(10)) ts = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] table, region = self._create_table_and_region() eS = ElectricalSeries('test_eS', data, region, timestamps=ts) eD = EventDetection('detection_method', eS, (1, 2, 3), (0.1, 0.2, 0.3)) self.assertEqual(eD.detection_method, 'detection_method') self.assertEqual(eD.source_electricalseries, eS) self.assertEqual(eD.source_idx, (1, 2, 3)) self.assertEqual(eD.times, (0.1, 0.2, 0.3)) self.assertEqual(eD.unit, 'seconds') class EventWaveformConstructor(TestCase): def _create_table_and_region(self): table = make_electrode_table() region = DynamicTableRegion( name='electrodes', data=[0, 2], description='the first and third electrodes', table=table ) return table, region def test_init(self): table, region = self._create_table_and_region() sES = SpikeEventSeries('test_sES', list(range(10)), list(range(10)), region) ew = EventWaveform(sES) self.assertEqual(ew.spike_event_series['test_sES'], sES) self.assertEqual(ew['test_sES'], ew.spike_event_series['test_sES']) class ClusteringConstructor(TestCase): def test_init(self): times = [1.3, 2.3] num = [3, 4] peak_over_rms = [5.3, 6.3] with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): cc = Clustering(description='description', num=num, peak_over_rms=peak_over_rms, times=times) self.assertEqual(cc.description, 'description') self.assertEqual(cc.num, num) self.assertEqual(cc.peak_over_rms, peak_over_rms) self.assertEqual(cc.times, times) class ClusterWaveformsConstructor(TestCase): def test_init(self): times = [1.3, 2.3] num = [3, 4] peak_over_rms = [5.3, 6.3] with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): cc = Clustering(description='description', num=num, peak_over_rms=peak_over_rms, times=times) means = [[7.3, 7.3]] stdevs = [[8.3, 8.3]] with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): cw = ClusterWaveforms( clustering_interface=cc, waveform_filtering='filtering', waveform_mean=means, waveform_sd=stdevs ) self.assertEqual(cw.clustering_interface, cc) self.assertEqual(cw.waveform_filtering, 'filtering') self.assertEqual(cw.waveform_mean, means) self.assertEqual(cw.waveform_sd, stdevs) class LFPTest(TestCase): def _create_table_and_region(self): table = make_electrode_table() region = DynamicTableRegion( name='electrodes', data=[0, 2], description='the first and third electrodes', table=table ) return table, region def test_add_electrical_series(self): lfp = LFP() table, region = self._create_table_and_region() eS = ElectricalSeries('test_eS', [0, 1, 2, 3], region, timestamps=[0.1, 0.2, 0.3, 0.4]) lfp.add_electrical_series(eS) self.assertEqual(lfp.electrical_series.get('test_eS'), eS) class FilteredEphysTest(TestCase): def _create_table_and_region(self): table = make_electrode_table() region = DynamicTableRegion( name='electrodes', data=[0, 2], description='the first and third electrodes', table=table ) return table, region def test_init(self): table, region = self._create_table_and_region() eS = ElectricalSeries('test_eS', [0, 1, 2, 3], region, timestamps=[0.1, 0.2, 0.3, 0.4]) fe = FilteredEphys(eS) self.assertEqual(fe.electrical_series.get('test_eS'), eS) self.assertEqual(fe['test_eS'], fe.electrical_series.get('test_eS')) def test_add_electrical_series(self): fe = FilteredEphys() table, region = self._create_table_and_region() eS = ElectricalSeries('test_eS', [0, 1, 2, 3], region, timestamps=[0.1, 0.2, 0.3, 0.4]) fe.add_electrical_series(eS) self.assertEqual(fe.electrical_series.get('test_eS'), eS) self.assertEqual(fe['test_eS'], fe.electrical_series.get('test_eS')) class FeatureExtractionConstructor(TestCase): def _create_table_and_region(self): table = make_electrode_table() region = DynamicTableRegion( name='electrodes', data=[0, 2], description='the first and third electrodes', table=table ) return table, region def test_init(self): event_times = [1.9, 3.5] table, region = self._create_table_and_region() description = ['desc1', 'desc2', 'desc3'] features = [[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] fe = FeatureExtraction(region, description, event_times, features) self.assertEqual(fe.description, description) self.assertEqual(fe.times, event_times) self.assertEqual(fe.features, features) def test_invalid_init_mismatched_event_times(self): event_times = [] # Need 1 event time but give 0 table, region = self._create_table_and_region() description = ['desc1', 'desc2', 'desc3'] features = [[[0, 1, 2], [3, 4, 5]]] self.assertRaises(ValueError, FeatureExtraction, region, description, event_times, features) def test_invalid_init_mismatched_electrodes(self): event_times = [1] table = make_electrode_table() region = DynamicTableRegion(name='electrodes', data=[0], description='the first electrode', table=table) description = ['desc1', 'desc2', 'desc3'] features = [[[0, 1, 2], [3, 4, 5]]] self.assertRaises(ValueError, FeatureExtraction, region, description, event_times, features) def test_invalid_init_mismatched_description(self): event_times = [1] table, region = self._create_table_and_region() description = ['desc1', 'desc2', 'desc3', 'desc4'] # Need 3 descriptions but give 4 features = [[[0, 1, 2], [3, 4, 5]]] self.assertRaises(ValueError, FeatureExtraction, region, description, event_times, features) def test_invalid_init_mismatched_description2(self): event_times = [1] table, region = self._create_table_and_region() description = ['desc1', 'desc2', 'desc3'] features = [[0, 1, 2], [3, 4, 5]] # Need 3D feature array but give only 2D array self.assertRaises(ValueError, FeatureExtraction, region, description, event_times, features) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_epoch.py0000644000175100001730000001047614467767506017144 0ustar00runnerdockerimport numpy as np import pandas as pd from datetime import datetime from dateutil import tz from pynwb.epoch import TimeIntervals from pynwb import TimeSeries, NWBFile from pynwb.base import TimeSeriesReference, TimeSeriesReferenceVectorData from pynwb.testing import TestCase class TimeIntervalsTest(TestCase): def test_init(self): tstamps = np.arange(1.0, 100.0, 0.1, dtype=np.float64) ts = TimeSeries(name="test_ts", data=list(range(len(tstamps))), unit='unit', timestamps=tstamps) ept = TimeIntervals(name='epochs', description="TimeIntervals unittest") self.assertEqual(ept.name, 'epochs') ept.add_interval(10.0, 20.0, ["test", "unittest", "pynwb"], ts) row = ept[0] self.assertEqual(row.index[0], 0) self.assertEqual(row.loc[0]['start_time'], 10.0) self.assertEqual(row.loc[0]['stop_time'], 20.0) self.assertEqual(row.loc[0]['tags'], ["test", "unittest", "pynwb"]) self.assertEqual(row.loc[0]['timeseries'], [(90, 100, ts)]) def get_timeseries(self): return [ TimeSeries(name='a', data=[1]*11, unit='unit', timestamps=np.linspace(0, 1, 11)), TimeSeries(name='b', data=[1]*13, unit='unit', timestamps=np.linspace(0.1, 5, 13)), ] def get_dataframe(self): tsa, tsb = self.get_timeseries() return pd.DataFrame({ 'foo': [1, 2, 3, 4], 'bar': ['fish', 'fowl', 'dog', 'cat'], 'start_time': [0.2, 0.25, 0.30, 0.35], 'stop_time': [0.25, 0.30, 0.40, 0.45], 'timeseries': [[TimeSeriesReference(idx_start=0, count=11, timeseries=tsa)], [TimeSeriesReference(idx_start=0, count=13, timeseries=tsb)], [], [TimeSeriesReference(idx_start=4, count=6, timeseries=tsb), TimeSeriesReference(idx_start=3, count=4, timeseries=tsa)]], 'keys': ['q', 'w', 'e', 'r'], 'tags': [[], [], ['fizz', 'buzz'], ['qaz']] }) def test_dataframe_roundtrip(self): df = self.get_dataframe() epochs = TimeIntervals.from_dataframe(df, name='test epochs') obtained = epochs.to_dataframe() self.assertTupleEqual(obtained.loc[3, 'timeseries'][1], df.loc[3, 'timeseries'][1]) self.assertIsInstance(epochs.timeseries, TimeSeriesReferenceVectorData) self.assertIsInstance(obtained.loc[3, 'timeseries'][1], TimeSeriesReference) self.assertIsInstance(df.loc[3, 'timeseries'][1], TimeSeriesReference) self.assertEqual(obtained.loc[2, 'foo'], df.loc[2, 'foo']) def test_dataframe_roundtrip_drop_ts(self): df = self.get_dataframe() epochs = TimeIntervals.from_dataframe(df, name='test epochs') self.assertIsInstance(epochs.timeseries, TimeSeriesReferenceVectorData) obtained = epochs.to_dataframe(exclude=set(['timeseries', 'timeseries_index'])) self.assertNotIn('timeseries', obtained.columns) self.assertEqual(obtained.loc[2, 'foo'], df.loc[2, 'foo']) def test_no_tags(self): nwbfile = NWBFile("a file with header data", "NB123A", datetime(1970, 1, 1, tzinfo=tz.tzutc())) df = self.get_dataframe() for i, row in df.iterrows(): nwbfile.add_epoch(start_time=row['start_time'], stop_time=row['stop_time']) def test_from_dataframe(self): df = pd.DataFrame({'start_time': [1., 2., 3.], 'stop_time': [2., 3., 4.], 'label': ['a', 'b', 'c']}, columns=('start_time', 'stop_time', 'label')) ti = TimeIntervals.from_dataframe(df, name='ti_name') self.assertEqual(ti.colnames, ('start_time', 'stop_time', 'label')) self.assertEqual(ti.columns[0].data, [1.0, 2.0, 3.0]) self.assertEqual(ti.columns[2].data, ['a', 'b', 'c']) def test_from_dataframe_missing_required_cols(self): df = pd.DataFrame({'start_time': [1., 2., 3.], 'label': ['a', 'b', 'c']}) with self.assertRaises(ValueError): TimeIntervals.from_dataframe(df, name='ti_name') def test_from_dataframe_missing_supplied_col(self): df = pd.DataFrame({'start_time': [1., 2., 3.], 'stop_time': [2., 3., 4.], 'label': ['a', 'b', 'c']}) with self.assertRaises(ValueError): TimeIntervals.from_dataframe(df, name='ti_name', columns=[{'name': 'not there'}]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_epoch_legacy.py0000644000175100001730000001101214467767506020453 0ustar00runnerdockerfrom pynwb.epoch import TimeIntervals from pynwb.testing import NWBH5IOMixin, TestCase from pynwb import NWBFile, NWBHDF5IO from pynwb.base import TimeSeries, TimeSeriesReference, TimeSeriesReferenceVectorData import numpy as np import h5py class TestTimeIntervalsIO(NWBH5IOMixin, TestCase): """ Test that reading NWB files with version 2.4 and earlier function correctly with the TimeIntervals type. In NWB 2.5 TimeIntervals.timeseries was updated to use the TimeSeriesReferenceVectorData type and to keep the API consistent old files are migrated on read to present the same API for those files. This is possible because the previous and updated schema are identical aside from the fact that a dedicated neurodata_type was created for the TimeIntervals.timeseries columns which is also used in the IntracellularRecordingTable type. This is technically a round-trip test, but without round-trip we can't test the object-mapper and including it here makes sure this gets included in code-coverage tests as well. """ def setUpContainer(self): """ Return placeholder epochs object. Tested epochs are added directly to the NWBFile in addContainer """ return TimeIntervals('epochs') def addContainer(self, nwbfile): """ Add the test epochs to the given NWBFile """ # Add some timeseries tsa, tsb = [ TimeSeries(name='a', data=np.arange(11), unit='flubs', timestamps=np.linspace(0, 1.0, 11)), TimeSeries(name='b', data=np.arange(13), unit='flubs', timestamps=np.linspace(0.1, 2.0, 13)), ] nwbfile.add_acquisition(tsa) nwbfile.add_acquisition(tsb) # Add a custom column nwbfile.add_epoch_column( name='temperature', description='average temperature (c) during epoch' ) # Add some epochs nwbfile.add_epoch( start_time=0.0, stop_time=0.5, timeseries=[tsa, tsb], tags='ambient', temperature=26.4, ) nwbfile.add_epoch( start_time=1.3, stop_time=4.1, timeseries=[tsa, ], tags='ambient', temperature=26.4, ) # reset the thing self.container = nwbfile.epochs def getContainer(self, nwbfile): """ Return the test epochs from the given NWBFile """ return nwbfile.epochs def test_legacy_format(self): description = 'a file to test writing and reading a %s' % self.container_type identifier = 'TEST_%s' % self.container_type nwbfile = NWBFile(description, identifier, self.start_time, file_create_date=self.create_date) self.addContainer(nwbfile) # write the file with NWBHDF5IO(self.filename, mode='w') as write_io: write_io.write(nwbfile, cache_spec=False) # Modify the HDF5 file to look like NWB 2.4 and earlier. This simply means # modifying the neurodata_type on the TimeIntervals.timeseries column with h5py.File(self.filename, mode='a') as infile: infile['/intervals/epochs/timeseries'].attrs['neurodata_type'] = 'VectorData' infile.attrs['nwb_version'] = '2.3.0' # Read the file back self.reader = NWBHDF5IO(self.filename, mode='r') self.read_nwbfile = self.reader.read() # Test that the VectorData column for timeseries has been converted to TimeSeriesReferenceVectorData self.assertIsInstance(self.read_nwbfile.epochs.timeseries, TimeSeriesReferenceVectorData) # Test that slicing into epochs.timeseries works as expected re = self.read_nwbfile.epochs.timeseries[0] self.assertIsInstance(re, TimeSeriesReference) self.assertTupleEqual((re[0], re[1], re[2].object_id), (0, 5, nwbfile.get_acquisition('a').object_id)) # Test that slicing into epochs works as expected re = self.read_nwbfile.epochs[0:1] self.assertListEqual(re.columns.tolist(), ['start_time', 'stop_time', 'temperature', 'tags', 'timeseries']) for i in re.loc[0, 'timeseries']: self.assertIsInstance(i, TimeSeriesReference) self.assertTupleEqual( (re.loc[0, 'timeseries'][0][0], re.loc[0, 'timeseries'][0][1], re.loc[0, 'timeseries'][0][2].object_id), (0, 5, nwbfile.get_acquisition('a').object_id)) self.assertTupleEqual( (re.loc[0, 'timeseries'][1][0], re.loc[0, 'timeseries'][1][1], re.loc[0, 'timeseries'][1][2].object_id), (0, 3, nwbfile.get_acquisition('b').object_id)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_extension.py0000644000175100001730000002001414467767506020047 0ustar00runnerdockerimport os import random import string from datetime import datetime from dateutil.tz import tzlocal from tempfile import gettempdir from hdmf.spec import RefSpec from hdmf.utils import get_docval, docval, popargs from pynwb import get_type_map, TimeSeries, NWBFile, register_class, load_namespaces, get_class from pynwb.spec import NWBNamespaceBuilder, NWBGroupSpec, NWBAttributeSpec, NWBDatasetSpec from pynwb.file import LabMetaData from pynwb.testing import TestCase, remove_test_file def id_generator(N=10): """ Generator a random string of characters. """ return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N)) class TestExtension(TestCase): def setUp(self): self.tempdir = gettempdir() self.prefix = id_generator() self.ext_source = '%s_extension.yaml' % self.prefix self.ns_path = '%s_namespace.yaml' % self.prefix def tearDown(self): for f in (self.ext_source, self.ns_path): path = os.path.join(self.tempdir, f) remove_test_file(path) def test_export(self): ns_builder = NWBNamespaceBuilder('Extension for use in my Lab', self.prefix, version='0.1.0') ext1 = NWBGroupSpec('A custom ElectricalSeries for my lab', attributes=[NWBAttributeSpec(name='trode_id', doc='the tetrode id', dtype='int')], neurodata_type_inc='ElectricalSeries', neurodata_type_def='TetrodeSeries') ns_builder.add_spec(self.ext_source, ext1) ns_builder.export(self.ns_path, outdir=self.tempdir) def test_load_namespace(self): self.test_export() get_type_map(extensions=os.path.join(self.tempdir, self.ns_path)) def test_get_class(self): self.test_export() type_map = get_type_map(extensions=os.path.join(self.tempdir, self.ns_path)) type_map.get_dt_container_cls('TetrodeSeries', self.prefix) def test_load_namespace_with_reftype_attribute(self): ns_builder = NWBNamespaceBuilder('Extension for use in my Lab', self.prefix, version='0.1.0') test_ds_ext = NWBDatasetSpec(doc='test dataset to add an attr', name='test_data', shape=(None,), attributes=[NWBAttributeSpec(name='target_ds', doc='the target the dataset applies to', dtype=RefSpec('TimeSeries', 'object'))], neurodata_type_def='my_new_type') ns_builder.add_spec(self.ext_source, test_ds_ext) ns_builder.export(self.ns_path, outdir=self.tempdir) get_type_map(extensions=os.path.join(self.tempdir, self.ns_path)) def test_load_namespace_with_reftype_attribute_check_autoclass_const(self): ns_builder = NWBNamespaceBuilder('Extension for use in my Lab', self.prefix, version='0.1.0') test_ds_ext = NWBDatasetSpec(doc='test dataset to add an attr', name='test_data', shape=(None,), attributes=[NWBAttributeSpec(name='target_ds', doc='the target the dataset applies to', dtype=RefSpec('TimeSeries', 'object'))], neurodata_type_def='my_new_type') ns_builder.add_spec(self.ext_source, test_ds_ext) ns_builder.export(self.ns_path, outdir=self.tempdir) type_map = get_type_map(extensions=os.path.join(self.tempdir, self.ns_path)) my_new_type = type_map.get_dt_container_cls('my_new_type', self.prefix) docval = None for tmp in get_docval(my_new_type.__init__): if tmp['name'] == 'target_ds': docval = tmp break self.assertIsNotNone(docval) self.assertEqual(docval['type'], TimeSeries) def test_lab_meta(self): ns_builder = NWBNamespaceBuilder('Extension for use in my Lab', self.prefix, version='0.1.0') test_meta_ext = NWBGroupSpec( neurodata_type_def='MyTestMetaData', neurodata_type_inc='LabMetaData', doc='my test meta data', attributes=[ NWBAttributeSpec(name='test_attr', dtype='float', doc='test_dtype')]) ns_builder.add_spec(self.ext_source, test_meta_ext) ns_builder.export(self.ns_path, outdir=self.tempdir) ns_abs_path = os.path.join(self.tempdir, self.ns_path) load_namespaces(ns_abs_path) @register_class('MyTestMetaData', self.prefix) class MyTestMetaData(LabMetaData): __nwbfields__ = ('test_attr',) @docval({'name': 'name', 'type': str, 'doc': 'name'}, {'name': 'test_attr', 'type': float, 'doc': 'test attribute'}) def __init__(self, **kwargs): test_attr = popargs('test_attr', kwargs) super().__init__(**kwargs) self.test_attr = test_attr nwbfile = NWBFile("a file with header data", "NB123A", datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal())) nwbfile.add_lab_meta_data(MyTestMetaData(name='test_name', test_attr=5.)) def test_lab_meta_auto(self): ns_builder = NWBNamespaceBuilder('Extension for use in my Lab', self.prefix, version='0.1.0') test_meta_ext = NWBGroupSpec( neurodata_type_def='MyTestMetaData', neurodata_type_inc='LabMetaData', doc='my test meta data', attributes=[ NWBAttributeSpec(name='test_attr', dtype='float', doc='test_dtype')]) ns_builder.add_spec(self.ext_source, test_meta_ext) ns_builder.export(self.ns_path, outdir=self.tempdir) ns_abs_path = os.path.join(self.tempdir, self.ns_path) load_namespaces(ns_abs_path) MyTestMetaData = get_class('MyTestMetaData', self.prefix) nwbfile = NWBFile("a file with header data", "NB123A", datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal())) nwbfile.add_lab_meta_data(MyTestMetaData(name='test_name', test_attr=5.)) class TestCatchDupNS(TestCase): def setUp(self): self.tempdir = gettempdir() self.prefix = id_generator() self.ext_source1 = '%s_extension1.yaml' % self.prefix self.ns_path1 = '%s_namespace1.yaml' % self.prefix self.ext_source2 = '%s_extension2.yaml' % self.prefix self.ns_path2 = '%s_namespace2.yaml' % self.prefix def tearDown(self): files = (self.ext_source1, self.ns_path1, self.ext_source2, self.ns_path2) for f in files: path = os.path.join(self.tempdir, f) remove_test_file(path) def test_catch_dup_name(self): ns_builder1 = NWBNamespaceBuilder('Extension for us in my Lab', "pynwb_test_extension1", version='0.1.0') ext1 = NWBGroupSpec('A custom ElectricalSeries for my lab', attributes=[NWBAttributeSpec(name='trode_id', doc='the tetrode id', dtype='int')], neurodata_type_inc='ElectricalSeries', neurodata_type_def='TetrodeSeries') ns_builder1.add_spec(self.ext_source1, ext1) ns_builder1.export(self.ns_path1, outdir=self.tempdir) ns_builder2 = NWBNamespaceBuilder('Extension for us in my Lab', "pynwb_test_extension1", version='0.1.0') ext2 = NWBGroupSpec('A custom ElectricalSeries for my lab', attributes=[NWBAttributeSpec(name='trode_id', doc='the tetrode id', dtype='int')], neurodata_type_inc='ElectricalSeries', neurodata_type_def='TetrodeSeries') ns_builder2.add_spec(self.ext_source2, ext2) ns_builder2.export(self.ns_path2, outdir=self.tempdir) type_map = get_type_map(extensions=os.path.join(self.tempdir, self.ns_path1)) type_map.load_namespaces(os.path.join(self.tempdir, self.ns_path2)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_file.py0000644000175100001730000006613314467767506016766 0ustar00runnerdockerimport numpy as np import pandas as pd from datetime import datetime, timedelta from dateutil.tz import tzlocal, tzutc from pynwb import NWBFile, TimeSeries, NWBHDF5IO from pynwb.base import Image, Images from pynwb.file import Subject, ElectrodeTable, _add_missing_timezone from pynwb.epoch import TimeIntervals from pynwb.ecephys import ElectricalSeries from pynwb.testing import TestCase, remove_test_file class NWBFileTest(TestCase): def setUp(self): self.start = datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal()) self.ref_time = datetime(1979, 1, 1, 0, tzinfo=tzutc()) self.create = [datetime(2017, 5, 1, 12, tzinfo=tzlocal()), datetime(2017, 5, 2, 13, 0, 0, 1, tzinfo=tzutc()), datetime(2017, 5, 2, 14, tzinfo=tzutc())] self.path = 'nwbfile_test.h5' self.nwbfile = NWBFile(session_description='a test session description for a test NWBFile', identifier='FILE123', session_start_time=self.start, file_create_date=self.create, timestamps_reference_time=self.ref_time, experimenter='A test experimenter', lab='a test lab', institution='a test institution', experiment_description='a test experiment description', session_id='test1', notes='my notes', pharmacology='drugs', protocol='protocol', related_publications='my pubs', slices='my slices', surgery='surgery', virus='a virus', source_script='noscript', source_script_file_name='nofilename', stimulus_notes='test stimulus notes', data_collection='test data collection notes', keywords=('these', 'are', 'keywords')) def test_constructor(self): self.assertEqual(self.nwbfile.session_description, 'a test session description for a test NWBFile') self.assertEqual(self.nwbfile.identifier, 'FILE123') self.assertEqual(self.nwbfile.session_start_time, self.start) self.assertEqual(self.nwbfile.file_create_date, self.create) self.assertEqual(self.nwbfile.lab, 'a test lab') self.assertEqual(self.nwbfile.experimenter, ('A test experimenter',)) self.assertEqual(self.nwbfile.institution, 'a test institution') self.assertEqual(self.nwbfile.experiment_description, 'a test experiment description') self.assertEqual(self.nwbfile.session_id, 'test1') self.assertEqual(self.nwbfile.stimulus_notes, 'test stimulus notes') self.assertEqual(self.nwbfile.data_collection, 'test data collection notes') self.assertEqual(self.nwbfile.related_publications, ('my pubs',)) self.assertEqual(self.nwbfile.source_script, 'noscript') self.assertEqual(self.nwbfile.source_script_file_name, 'nofilename') self.assertEqual(self.nwbfile.keywords, ('these', 'are', 'keywords')) self.assertEqual(self.nwbfile.timestamps_reference_time, self.ref_time) def test_create_electrode_group(self): name = 'example_electrode_group' desc = 'An example electrode' loc = 'an example location' d = self.nwbfile.create_device('a fake device') elecgrp = self.nwbfile.create_electrode_group(name, desc, loc, d) self.assertEqual(elecgrp.description, desc) self.assertEqual(elecgrp.location, loc) self.assertIs(elecgrp.device, d) def test_create_custom_intervals(self): df_words = pd.DataFrame({'start_time': [.1, 2.], 'stop_time': [.8, 2.3], 'label': ['hello', 'there']}) words = TimeIntervals.from_dataframe(df_words, name='words') self.nwbfile.add_time_intervals(words) self.assertEqual(self.nwbfile.intervals['words'], words) def test_create_electrode_group_invalid_index(self): """ Test the case where the user creates an electrode table region with indexes that are out of range of the amount of electrodes added. """ nwbfile = NWBFile('a', 'b', datetime.now(tzlocal())) device = nwbfile.create_device('a') elecgrp = nwbfile.create_electrode_group('a', 'b', device=device, location='a') for i in range(4): nwbfile.add_electrode(location='a', group=elecgrp, id=i) with self.assertRaises(IndexError): nwbfile.create_electrode_table_region(list(range(6)), 'test') def test_access_group_after_io(self): """ Motivated by #739 """ nwbfile = NWBFile('a', 'b', datetime.now(tzlocal())) device = nwbfile.create_device('a') elecgrp = nwbfile.create_electrode_group('a', 'b', device=device, location='a') nwbfile.add_electrode(location='a', group=elecgrp, id=0) with NWBHDF5IO('electrodes_mwe.nwb', 'w') as io: io.write(nwbfile) with NWBHDF5IO('electrodes_mwe.nwb', 'a') as io: nwbfile_i = io.read() for aa, bb in zip(nwbfile_i.electrodes['group'][:], nwbfile.electrodes['group'][:]): self.assertEqual(aa.name, bb.name) for i in range(4): nwbfile.add_electrode(location='a', group=elecgrp, id=i + 1) with NWBHDF5IO('electrodes_mwe.nwb', 'w') as io: io.write(nwbfile) with NWBHDF5IO('electrodes_mwe.nwb', 'a') as io: nwbfile_i = io.read() for aa, bb in zip(nwbfile_i.electrodes['group'][:], nwbfile.electrodes['group'][:]): self.assertEqual(aa.name, bb.name) remove_test_file("electrodes_mwe.nwb") def test_access_processing(self): self.nwbfile.create_processing_module('test_mod', 'test_description') # test deprecate .modules with self.assertWarnsWith(DeprecationWarning, 'NWBFile.modules has been replaced by NWBFile.processing.'): modules = self.nwbfile.modules['test_mod'] self.assertIs(self.nwbfile.processing['test_mod'], modules) def test_epoch_tags(self): tags1 = ['t1', 't2'] tags2 = ['t3', 't4'] tstamps = np.arange(1.0, 100.0, 0.1, dtype=np.float64) ts = TimeSeries("test_ts", list(range(len(tstamps))), 'unit', timestamps=tstamps) expected_tags = tags1 + tags2 self.nwbfile.add_epoch(0.0, 1.0, tags1, ts) self.nwbfile.add_epoch(0.0, 1.0, tags2, ts) tags = self.nwbfile.epoch_tags self.assertEqual(set(expected_tags), set(tags)) def test_add_acquisition(self): self.nwbfile.add_acquisition(TimeSeries('test_ts', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5])) self.assertEqual(len(self.nwbfile.acquisition), 1) def test_add_stimulus(self): self.nwbfile.add_stimulus(TimeSeries('test_ts', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5])) self.assertEqual(len(self.nwbfile.stimulus), 1) def test_add_stimulus_template(self): self.nwbfile.add_stimulus_template(TimeSeries('test_ts', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5])) self.assertEqual(len(self.nwbfile.stimulus_template), 1) def test_add_stimulus_template_images(self): image1 = Image(name='test_image1', data=np.ones((10, 10))) images = Images(name='images_name', images=[image1]) self.nwbfile.add_stimulus_template(images) self.assertEqual(len(self.nwbfile.stimulus_template), 1) def test_add_analysis(self): self.nwbfile.add_analysis(TimeSeries('test_ts', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5])) self.assertEqual(len(self.nwbfile.analysis), 1) def test_add_acquisition_check_dups(self): self.nwbfile.add_acquisition(TimeSeries('test_ts', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5])) with self.assertRaises(ValueError): self.nwbfile.add_acquisition(TimeSeries('test_ts', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5])) def test_get_acquisition_empty(self): with self.assertRaisesWith(ValueError, "acquisition of NWBFile 'root' is empty."): self.nwbfile.get_acquisition() def test_get_acquisition_multiple_elements(self): self.nwbfile.add_acquisition(TimeSeries('test_ts1', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5])) self.nwbfile.add_acquisition(TimeSeries('test_ts2', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5])) msg = "More than one element in acquisition of NWBFile 'root' -- must specify a name." with self.assertRaisesWith(ValueError, msg): self.nwbfile.get_acquisition() def test_add_acquisition_invalid_name(self): self.nwbfile.add_acquisition(TimeSeries('test_ts', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5])) msg = "\"'TEST_TS' not found in acquisition of NWBFile 'root'.\"" with self.assertRaisesWith(KeyError, msg): self.nwbfile.get_acquisition("TEST_TS") def test_set_electrode_table(self): table = ElectrodeTable() dev1 = self.nwbfile.create_device('dev1') group = self.nwbfile.create_electrode_group('tetrode1', 'tetrode description', 'tetrode location', dev1) table.add_row(location='CA1', group=group, group_name='tetrode1') table.add_row(location='CA1', group=group, group_name='tetrode1') table.add_row(location='CA1', group=group, group_name='tetrode1') table.add_row(location='CA1', group=group, group_name='tetrode1') self.nwbfile.set_electrode_table(table) self.assertIs(self.nwbfile.electrodes, table) self.assertIs(table.parent, self.nwbfile) def test_add_unit_column(self): self.nwbfile.add_unit_column('unit_type', 'the type of unit') self.assertEqual(self.nwbfile.units.colnames, ('unit_type',)) def test_add_unit(self): self.nwbfile.add_unit(id=1) self.assertEqual(len(self.nwbfile.units), 1) self.nwbfile.add_unit(id=2) self.nwbfile.add_unit(id=3) self.assertEqual(len(self.nwbfile.units), 3) def test_add_trial_column(self): self.nwbfile.add_trial_column('trial_type', 'the type of trial') self.assertEqual(self.nwbfile.trials.colnames, ('start_time', 'stop_time', 'trial_type')) def test_add_trial(self): self.nwbfile.add_trial(start_time=10.0, stop_time=20.0) self.assertEqual(len(self.nwbfile.trials), 1) self.nwbfile.add_trial(start_time=30.0, stop_time=40.0) self.nwbfile.add_trial(start_time=50.0, stop_time=70.0) self.assertEqual(len(self.nwbfile.trials), 3) def test_add_invalid_times_column(self): self.nwbfile.add_invalid_times_column('comments', 'description of reason for omitting time') self.assertEqual(self.nwbfile.invalid_times.colnames, ('start_time', 'stop_time', 'comments')) def test_add_invalid_time_interval(self): self.nwbfile.add_invalid_time_interval(start_time=0.0, stop_time=12.0) self.assertEqual(len(self.nwbfile.invalid_times), 1) self.nwbfile.add_invalid_time_interval(start_time=15.0, stop_time=16.0) self.nwbfile.add_invalid_time_interval(start_time=17.0, stop_time=20.5) self.assertEqual(len(self.nwbfile.invalid_times), 3) def test_add_invalid_time_w_ts(self): ts = TimeSeries(name='name', data=[1.2], rate=1.0, unit='na') self.nwbfile.add_invalid_time_interval(start_time=18.0, stop_time=20.6, timeseries=ts, tags=('hi', 'there')) def test_add_electrode(self): dev1 = self.nwbfile.create_device(name='dev1') group = self.nwbfile.create_electrode_group( name='tetrode1', description='tetrode description', location='tetrode location', device=dev1 ) self.nwbfile.add_electrode( x=1.0, y=2.0, z=3.0, imp=-1.0, location='CA1', filtering='none', group=group, id=1 ) elec = self.nwbfile.electrodes[0] self.assertEqual(elec.index[0], 1) self.assertEqual(elec.iloc[0]['x'], 1.0) self.assertEqual(elec.iloc[0]['y'], 2.0) self.assertEqual(elec.iloc[0]['z'], 3.0) self.assertEqual(elec.iloc[0]['location'], 'CA1') self.assertEqual(elec.iloc[0]['filtering'], 'none') self.assertEqual(elec.iloc[0]['group'], group) def test_add_electrode_some_opt(self): dev1 = self.nwbfile.create_device(name='dev1') group = self.nwbfile.create_electrode_group( name='tetrode1', description='tetrode description', location='tetrode location', device=dev1 ) self.nwbfile.add_electrode( x=1.0, y=2.0, z=3.0, imp=-1.0, location='CA1', filtering='none', group=group, id=1, rel_x=4.0, rel_y=5.0, rel_z=6.0, reference='ref1' ) self.nwbfile.add_electrode( x=1.0, y=2.0, z=3.0, imp=-1.0, location='CA1', filtering='none', group=group, id=2, rel_x=7.0, rel_y=8.0, rel_z=9.0, reference='ref2' ) elec = self.nwbfile.electrodes[0] self.assertEqual(elec.iloc[0]['rel_x'], 4.0) self.assertEqual(elec.iloc[0]['rel_y'], 5.0) self.assertEqual(elec.iloc[0]['rel_z'], 6.0) self.assertEqual(elec.iloc[0]['reference'], 'ref1') elec = self.nwbfile.electrodes[1] self.assertEqual(elec.iloc[0]['rel_x'], 7.0) self.assertEqual(elec.iloc[0]['rel_y'], 8.0) self.assertEqual(elec.iloc[0]['rel_z'], 9.0) self.assertEqual(elec.iloc[0]['reference'], 'ref2') def test_add_electrode_missing_location(self): """ Test the case where the user creates an electrode table region with indexes that are out of range of the amount of electrodes added. """ nwbfile = NWBFile('a', 'b', datetime.now(tzlocal())) device = nwbfile.create_device('a') elecgrp = nwbfile.create_electrode_group('a', 'b', device=device, location='a') msg = "The 'location' argument is required when creating an electrode." with self.assertRaisesWith(ValueError, msg): nwbfile.add_electrode(group=elecgrp, id=0) def test_add_electrode_missing_group(self): """ Test the case where the user creates an electrode table region with indexes that are out of range of the amount of electrodes added. """ nwbfile = NWBFile('a', 'b', datetime.now(tzlocal())) msg = "The 'group' argument is required when creating an electrode." with self.assertRaisesWith(ValueError, msg): nwbfile.add_electrode(location='a', id=0) def test_all_children(self): ts1 = TimeSeries('test_ts1', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5]) ts2 = TimeSeries('test_ts2', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5]) self.nwbfile.add_acquisition(ts1) self.nwbfile.add_acquisition(ts2) name = 'example_electrode_group' desc = 'An example electrode' loc = 'an example location' device = self.nwbfile.create_device('a fake device') elecgrp = self.nwbfile.create_electrode_group(name, desc, loc, device) children = self.nwbfile.all_children() self.assertIn(ts1, children) self.assertIn(ts2, children) self.assertIn(device, children) self.assertIn(elecgrp, children) def test_fail_if_source_script_file_name_without_source_script(self): with self.assertRaises(ValueError): # <-- source_script_file_name without source_script is not allowed NWBFile('a test session description for a test NWBFile', 'FILE123', self.start, source_script=None, source_script_file_name='nofilename') def test_get_neurodata_type(self): ts1 = TimeSeries('test_ts1', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5]) ts2 = TimeSeries('test_ts2', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5]) self.nwbfile.add_acquisition(ts1) self.nwbfile.add_acquisition(ts2) p1 = ts1.get_ancestor(neurodata_type='NWBFile') self.assertIs(p1, self.nwbfile) p2 = ts2.get_ancestor(neurodata_type='NWBFile') self.assertIs(p2, self.nwbfile) def test_print_units(self): self.nwbfile.add_unit(spike_times=[1., 2., 3.]) expected = """units pynwb.misc.Units at 0x%d Fields: colnames: ['spike_times'] columns: ( spike_times_index , spike_times ) description: Autogenerated by NWBFile id: id waveform_unit: volts """ expected = expected % id(self.nwbfile.units) self.assertEqual(str(self.nwbfile.units), expected) def test_copy(self): self.nwbfile.add_unit(spike_times=[1., 2., 3.]) device = self.nwbfile.create_device('a') elecgrp = self.nwbfile.create_electrode_group('a', 'b', device=device, location='a') self.nwbfile.add_electrode(x=1.0, location='a', group=elecgrp, id=0) self.nwbfile.add_electrode(x=2.0, location='b', group=elecgrp) elec_region = self.nwbfile.create_electrode_table_region([1], 'name') ts1 = TimeSeries('test_ts1', [0, 1, 2, 3, 4, 5], 'grams', timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5]) ts2 = ElectricalSeries('test_ts2', [0, 1, 2, 3, 4, 5], electrodes=elec_region, timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5]) self.nwbfile.add_acquisition(ts1) self.nwbfile.add_acquisition(ts2) self.nwbfile.add_trial(start_time=50.0, stop_time=70.0) self.nwbfile.add_invalid_times_column('comments', 'description of reason for omitting time') self.nwbfile.create_processing_module('test_mod', 'test_description') self.nwbfile.create_time_intervals('custom_interval', 'a custom time interval') self.nwbfile.intervals['custom_interval'].add_interval(start_time=10., stop_time=20.) newfile = self.nwbfile.copy() # test dictionaries self.assertIs(self.nwbfile.devices['a'], newfile.devices['a']) self.assertIs(self.nwbfile.acquisition['test_ts1'], newfile.acquisition['test_ts1']) self.assertIs(self.nwbfile.acquisition['test_ts2'], newfile.acquisition['test_ts2']) self.assertIs(self.nwbfile.processing['test_mod'], newfile.processing['test_mod']) # test dynamic tables self.assertIsNot(self.nwbfile.electrodes, newfile.electrodes) self.assertIs(self.nwbfile.electrodes['x'], newfile.electrodes['x']) self.assertIsNot(self.nwbfile.units, newfile.units) self.assertIs(self.nwbfile.units['spike_times'], newfile.units['spike_times']) self.assertIsNot(self.nwbfile.trials, newfile.trials) self.assertIsNot(self.nwbfile.trials.parent, newfile.trials.parent) self.assertIs(self.nwbfile.trials.id, newfile.trials.id) self.assertIs(self.nwbfile.trials['start_time'], newfile.trials['start_time']) self.assertIs(self.nwbfile.trials['stop_time'], newfile.trials['stop_time']) self.assertIsNot(self.nwbfile.invalid_times, newfile.invalid_times) self.assertTupleEqual(self.nwbfile.invalid_times.colnames, newfile.invalid_times.colnames) self.assertIsNot(self.nwbfile.intervals['custom_interval'], newfile.intervals['custom_interval']) self.assertTupleEqual(self.nwbfile.intervals['custom_interval'].colnames, newfile.intervals['custom_interval'].colnames) self.assertIs(self.nwbfile.intervals['custom_interval']['start_time'], newfile.intervals['custom_interval']['start_time']) self.assertIs(self.nwbfile.intervals['custom_interval']['stop_time'], newfile.intervals['custom_interval']['stop_time']) def test_multi_experimenters(self): self.nwbfile = NWBFile('a test session description for a test NWBFile', 'FILE123', self.start, experimenter=('experimenter1', 'experimenter2')) self.assertTupleEqual(self.nwbfile.experimenter, ('experimenter1', 'experimenter2')) def test_multi_publications(self): self.nwbfile = NWBFile('a test session description for a test NWBFile', 'FILE123', self.start, related_publications=('pub1', 'pub2')) self.assertTupleEqual(self.nwbfile.related_publications, ('pub1', 'pub2')) class SubjectTest(TestCase): def setUp(self): self.subject = Subject( age='P90D', age__reference="birth", description='An unfortunate rat', genotype='WT', sex='M', species='Rattus norvegicus', subject_id='RAT123', weight='2 kg', date_of_birth=datetime(2017, 5, 1, 12, tzinfo=tzlocal()), strain='my_strain', ) self.start = datetime(2017, 5, 1, 12, tzinfo=tzlocal()) self.path = 'nwbfile_test.h5' self.nwbfile = NWBFile( 'a test session description for a test NWBFile', 'FILE123', self.start, experimenter='A test experimenter', lab='a test lab', institution='a test institution', experiment_description='a test experiment description', session_id='test1', subject=self.subject, ) def test_constructor(self): self.assertEqual(self.subject.age, 'P90D') self.assertEqual(self.subject.age__reference, "birth") self.assertEqual(self.subject.description, 'An unfortunate rat') self.assertEqual(self.subject.genotype, 'WT') self.assertEqual(self.subject.sex, 'M') self.assertEqual(self.subject.species, 'Rattus norvegicus') self.assertEqual(self.subject.subject_id, 'RAT123') self.assertEqual(self.subject.weight, '2 kg') self.assertEqual(self.subject.date_of_birth, datetime(2017, 5, 1, 12, tzinfo=tzlocal())) self.assertEqual(self.subject.strain, 'my_strain') def test_nwbfile_constructor(self): self.assertIs(self.nwbfile.subject, self.subject) def test_weight_float(self): subject = Subject( subject_id='RAT123', weight=2.3, ) self.assertEqual(subject.weight, '2.3 kg') def test_age_reference_arg_check(self): with self.assertRaisesWith(ValueError, "age__reference, if supplied, must be 'birth' or 'gestational'."): Subject(subject_id='RAT123', age='P90D', age__reference='brth') def test_age_regression_1(self): subject = Subject( age='P90D', description='An unfortunate rat', subject_id='RAT123', ) self.assertEqual(subject.age, 'P90D') self.assertEqual(subject.age__reference, "birth") self.assertEqual(subject.description, 'An unfortunate rat') self.assertEqual(subject.subject_id, 'RAT123') def test_age_regression_2(self): subject = Subject( description='An unfortunate rat', subject_id='RAT123', ) self.assertEqual(subject.description, 'An unfortunate rat') self.assertEqual(subject.subject_id, 'RAT123') def test_subject_age_duration(self): subject = Subject( subject_id='RAT123', age=timedelta(seconds=99999) ) self.assertEqual(subject.age, "P1DT3H46M39S") class TestCacheSpec(TestCase): def setUp(self): self.path = 'unittest_cached_spec.nwb' def tearDown(self): remove_test_file(self.path) def test_simple(self): nwbfile = NWBFile(' ', ' ', datetime.now(tzlocal()), file_create_date=datetime.now(tzlocal()), institution='University of California, San Francisco', lab='Chang Lab') with NWBHDF5IO(self.path, 'w') as io: io.write(nwbfile) with NWBHDF5IO(self.path, 'r', load_namespaces=True) as reader: nwbfile = reader.read() class TestNoCacheSpec(TestCase): def setUp(self): self.path = 'unittest_cached_spec.nwb' def tearDown(self): remove_test_file(self.path) def test_simple(self): nwbfile = NWBFile(' ', ' ', datetime.now(tzlocal()), file_create_date=datetime.now(tzlocal()), institution='University of California, San Francisco', lab='Chang Lab') with NWBHDF5IO(self.path, 'w') as io: io.write(nwbfile, cache_spec=False) with self.assertWarnsWith(UserWarning, "No cached namespaces found in %s" % self.path): with NWBHDF5IO(self.path, 'r', load_namespaces=True) as reader: nwbfile = reader.read() class TestTimestampsRefDefault(TestCase): def setUp(self): self.start_time = datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal()) self.nwbfile = NWBFile('test session description', 'TEST123', self.start_time) def test_reftime_default(self): # 'timestamps_reference_time' should default to 'session_start_time' self.assertEqual(self.nwbfile.timestamps_reference_time, self.start_time) class TestTimestampsRefAware(TestCase): def setUp(self): self.start_time = datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal()) self.ref_time_notz = datetime(1979, 1, 1, 0, 0, 0) def test_reftime_tzaware(self): with self.assertRaises(ValueError): # 'timestamps_reference_time' must be a timezone-aware datetime NWBFile('test session description', 'TEST124', self.start_time, timestamps_reference_time=self.ref_time_notz) class TestTimezone(TestCase): def test_raise_warning__add_missing_timezone(self): with self.assertWarnsWith(UserWarning, "Date is missing timezone information. Updating to local timezone."): _add_missing_timezone(datetime(2017, 5, 1, 12)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_icephys.py0000644000175100001730000003516114467767506017510 0ustar00runnerdockerimport numpy as np from pynwb.icephys import ( PatchClampSeries, CurrentClampSeries, IZeroClampSeries, CurrentClampStimulusSeries, VoltageClampSeries, VoltageClampStimulusSeries, IntracellularElectrode, SweepTable, ) from pynwb.device import Device from pynwb.testing import TestCase from pynwb.file import NWBFile # Needed to test icephys functionality defined on NWBFile from datetime import datetime from dateutil.tz import tzlocal def GetElectrode(): device = Device(name='device_name') elec = IntracellularElectrode( name='test_iS', device=device, description='description', slice='slice', seal='seal', location='location', resistance='resistance', filtering='filtering', initial_access_resistance='initial_access_resistance', cell_id='this_cell', ) return elec class NWBFileICEphys(TestCase): """Test ICEphys-specific functionality on NWBFile""" def setUp(self): self.icephys_electrode = GetElectrode() def test_sweep_table_depractation_warn(self): msg = ("Use of SweepTable is deprecated. Use the IntracellularRecordingsTable " "instead. See also the NWBFile.add_intracellular_recordings function.") with self.assertWarnsWith(DeprecationWarning, msg): _ = NWBFile( session_description='NWBFile icephys test', identifier='NWB123', # required session_start_time=datetime(2017, 4, 3, 11, tzinfo=tzlocal()), ic_electrodes=[self.icephys_electrode, ], sweep_table=SweepTable()) def test_ic_electrodes_parameter_deprecation(self): # Make sure we warn when using the ic_electrodes parameter on NWBFile msg = "Use of the ic_electrodes parameter is deprecated. Use the icephys_electrodes parameter instead" with self.assertWarnsWith(DeprecationWarning, msg): _ = NWBFile( session_description='NWBFile icephys test', identifier='NWB123', # required session_start_time=datetime(2017, 4, 3, 11, tzinfo=tzlocal()), ic_electrodes=[self.icephys_electrode, ]) def test_icephys_electrodes_parameter(self): nwbfile = NWBFile( session_description='NWBFile icephys test', identifier='NWB123', # required session_start_time=datetime(2017, 4, 3, 11, tzinfo=tzlocal()), icephys_electrodes=[self.icephys_electrode, ]) self.assertEqual(nwbfile.get_icephys_electrode('test_iS'), self.icephys_electrode) def test_add_ic_electrode_deprecation(self): # Make sure we warn when using the add_ic_electrodes parameter on NWBFile nwbfile = NWBFile( session_description='NWBFile icephys test', identifier='NWB123', # required session_start_time=datetime(2017, 4, 3, 11, tzinfo=tzlocal())) msg = "NWBFile.add_ic_electrode has been replaced by NWBFile.add_icephys_electrode." with self.assertWarnsWith(DeprecationWarning, msg): nwbfile.add_ic_electrode(self.icephys_electrode) def test_ic_electrodes_attribute_deprecation(self): nwbfile = NWBFile( session_description='NWBFile icephys test', identifier='NWB123', # required session_start_time=datetime(2017, 4, 3, 11, tzinfo=tzlocal()), icephys_electrodes=[self.icephys_electrode, ]) # make sure NWBFile.ic_electrodes property warns msg = "NWBFile.ic_electrodes has been replaced by NWBFile.icephys_electrodes." with self.assertWarnsWith(DeprecationWarning, msg): nwbfile.ic_electrodes # make sure NWBFile.get_ic_electrode warns msg = "NWBFile.get_ic_electrode has been replaced by NWBFile.get_icephys_electrode." with self.assertWarnsWith(DeprecationWarning, msg): nwbfile.get_ic_electrode(self.icephys_electrode.name) def test_create_ic_electrode_deprecation(self): nwbfile = NWBFile( session_description='NWBFile icephys test', identifier='NWB123', # required session_start_time=datetime(2017, 4, 3, 11, tzinfo=tzlocal())) device = Device(name='device_name') msg = "NWBFile.create_ic_electrode has been replaced by NWBFile.create_icephys_electrode." with self.assertWarnsWith(DeprecationWarning, msg): nwbfile.create_ic_electrode( name='test_iS', device=device, description='description', slice='slice', seal='seal', location='location', resistance='resistance', filtering='filtering', initial_access_resistance='initial_access_resistance') class IntracellularElectrodeConstructor(TestCase): def test_constructor(self): device = Device(name='device_name') elec = IntracellularElectrode('test_iS', device, 'description', 'slice', 'seal', 'location', 'resistance', 'filtering', 'initial_access_resistance', 'this_cell') self.assertEqual(elec.name, 'test_iS') self.assertEqual(elec.device, device) self.assertEqual(elec.description, 'description') self.assertEqual(elec.slice, 'slice') self.assertEqual(elec.seal, 'seal') self.assertEqual(elec.location, 'location') self.assertEqual(elec.resistance, 'resistance') self.assertEqual(elec.filtering, 'filtering') self.assertEqual(elec.initial_access_resistance, 'initial_access_resistance') self.assertEqual(elec.cell_id, 'this_cell') class PatchClampSeriesConstructor(TestCase): def test_default(self): electrode_name = GetElectrode() pCS = PatchClampSeries('test_pCS', list(), 'unit', electrode_name, 1.0, timestamps=list()) self.assertEqual(pCS.name, 'test_pCS') self.assertEqual(pCS.unit, 'unit') self.assertEqual(pCS.electrode, electrode_name) self.assertEqual(pCS.gain, 1.0) def test_sweepNumber_valid(self): electrode_name = GetElectrode() pCS = PatchClampSeries('test_pCS', list(), 'unit', electrode_name, 1.0, timestamps=list(), sweep_number=4711) self.assertEqual(pCS.name, 'test_pCS') self.assertEqual(pCS.unit, 'unit') self.assertEqual(pCS.electrode, electrode_name) self.assertEqual(pCS.gain, 1.0) self.assertEqual(pCS.sweep_number, 4711) def test_sweepNumber_valid_np(self): electrode_name = GetElectrode() pCS = PatchClampSeries('test_pCS', list(), 'unit', electrode_name, 1.0, timestamps=list(), sweep_number=1) self.assertEqual(pCS.name, 'test_pCS') self.assertEqual(pCS.unit, 'unit') self.assertEqual(pCS.electrode, electrode_name) self.assertEqual(pCS.gain, 1.0) self.assertEqual(pCS.sweep_number, np.uint32(1)) def test_sweepNumber_large_and_valid(self): electrode_name = GetElectrode() pCS = PatchClampSeries('test_pCS', list(), 'unit', electrode_name, 1.0, timestamps=list(), sweep_number=np.uint64(2**63-1)) self.assertEqual(pCS.name, 'test_pCS') self.assertEqual(pCS.unit, 'unit') self.assertEqual(pCS.electrode, electrode_name) self.assertEqual(pCS.gain, 1.0) self.assertEqual(pCS.sweep_number, 2**63-1) def test_sweepNumber_throws_with_negative(self): electrode_name = GetElectrode() with self.assertRaises(ValueError): PatchClampSeries('test_pCS', list(), 'unit', electrode_name, 1.0, timestamps=list(), sweep_number=-1) def test_sweepNumber_throws_with_NaN(self): electrode_name = GetElectrode() with self.assertRaises(TypeError): PatchClampSeries('test_pCS', list(), 'unit', electrode_name, 1.0, timestamps=list(), sweep_number=float('nan')) def test_sweepNumber_throws_with_Float(self): electrode_name = GetElectrode() with self.assertRaises(TypeError): PatchClampSeries('test_pCS', list(), 'unit', electrode_name, 1.0, timestamps=list(), sweep_number=1.5) def test_data_shape(self): electrode_name = GetElectrode() with self.assertRaises(ValueError): PatchClampSeries( name="test_pCS", data=np.ones((30, 2)), unit="unit", electrode=electrode_name, gain=1.0, rate=100_000., ) class CurrentClampSeriesConstructor(TestCase): def test_init(self): electrode_name = GetElectrode() cCS = CurrentClampSeries('test_cCS', list(), electrode_name, 1.0, "stimset", 2.0, 3.0, 4.0, timestamps=list()) self.assertEqual(cCS.name, 'test_cCS') self.assertEqual(cCS.unit, 'volts') self.assertEqual(cCS.electrode, electrode_name) self.assertEqual(cCS.stimulus_description, "stimset") self.assertEqual(cCS.gain, 1.0) self.assertEqual(cCS.bias_current, 2.0) self.assertEqual(cCS.bridge_balance, 3.0) self.assertEqual(cCS.capacitance_compensation, 4.0) def test_unit_warning(self): electrode_name = GetElectrode() msg = "Unit 'unit' for CurrentClampSeries 'test_cCS' is ignored and will be set to 'volts' as per NWB 2.1.0." with self.assertWarnsWith(UserWarning, msg): cCS = CurrentClampSeries('test_cCS', list(), electrode_name, 1.0, "stimset", 2.0, 3.0, 4.0, timestamps=list(), unit='unit') self.assertEqual(cCS.unit, 'volts') class IZeroClampSeriesConstructor(TestCase): def test_init(self): electrode_name = GetElectrode() iZCS = IZeroClampSeries('test_iZCS', list(), electrode_name, 1.0, timestamps=list()) self.assertEqual(iZCS.name, 'test_iZCS') self.assertEqual(iZCS.unit, 'volts') self.assertEqual(iZCS.electrode, electrode_name) self.assertEqual(iZCS.gain, 1.0) self.assertEqual(iZCS.bias_current, 0.0) self.assertEqual(iZCS.bridge_balance, 0.0) self.assertEqual(iZCS.capacitance_compensation, 0.0) self.assertEqual(iZCS.stimulus_description, 'N/A') def test_unit_warning(self): electrode_name = GetElectrode() msg = "Unit 'unit' for IZeroClampSeries 'test_iZCS' is ignored and will be set to 'volts' as per NWB 2.1.0." with self.assertWarnsWith(UserWarning, msg): iZCS = IZeroClampSeries('test_iZCS', list(), electrode_name, 1.0, timestamps=list(), unit='unit') self.assertEqual(iZCS.unit, 'volts') def test_stim_desc_warning(self): electrode_name = GetElectrode() msg = ("Stimulus description 'desc' for IZeroClampSeries 'test_iZCS' is ignored and will be set to 'N/A' " "as per NWB 2.3.0.") with self.assertWarnsWith(UserWarning, msg): iZCS = IZeroClampSeries('test_iZCS', list(), electrode_name, 1.0, timestamps=list(), stimulus_description='desc') self.assertEqual(iZCS.stimulus_description, 'N/A') class CurrentClampStimulusSeriesConstructor(TestCase): def test_init(self): electrode_name = GetElectrode() cCSS = CurrentClampStimulusSeries('test_cCSS', list(), electrode_name, 1.0, timestamps=list()) self.assertEqual(cCSS.name, 'test_cCSS') self.assertEqual(cCSS.unit, 'amperes') self.assertEqual(cCSS.electrode, electrode_name) self.assertEqual(cCSS.gain, 1.0) def test_unit_warning(self): electrode_name = GetElectrode() msg = ("Unit 'unit' for CurrentClampStimulusSeries 'test_cCSS' is ignored and will be set " "to 'amperes' as per NWB 2.1.0.") with self.assertWarnsWith(UserWarning, msg): cCSS = CurrentClampStimulusSeries('test_cCSS', list(), electrode_name, 1.0, timestamps=list(), unit='unit') self.assertEqual(cCSS.unit, 'amperes') class VoltageClampSeriesConstructor(TestCase): def test_init(self): electrode_name = GetElectrode() vCS = VoltageClampSeries('test_vCS', list(), electrode_name, 1.0, "stimset", 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, timestamps=list()) self.assertEqual(vCS.name, 'test_vCS') self.assertEqual(vCS.unit, 'amperes') self.assertEqual(vCS.electrode, electrode_name) self.assertEqual(vCS.stimulus_description, "stimset") self.assertEqual(vCS.gain, 1.0) self.assertEqual(vCS.capacitance_fast, 2.0) self.assertEqual(vCS.capacitance_slow, 3.0) self.assertEqual(vCS.resistance_comp_bandwidth, 4.0) self.assertEqual(vCS.resistance_comp_correction, 5.0) self.assertEqual(vCS.resistance_comp_prediction, 6.0) self.assertEqual(vCS.whole_cell_capacitance_comp, 7.0) self.assertEqual(vCS.whole_cell_series_resistance_comp, 8.0) def test_unit_warning(self): electrode_name = GetElectrode() msg = "Unit 'unit' for VoltageClampSeries 'test_vCS' is ignored and will be set " \ "to 'amperes' as per NWB 2.1.0." with self.assertWarnsWith(UserWarning, msg): vCS = VoltageClampSeries('test_vCS', list(), electrode_name, 1.0, "stimset", 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, timestamps=list(), unit='unit') self.assertEqual(vCS.unit, 'amperes') class VoltageClampStimulusSeriesConstructor(TestCase): def test_init(self): electrode_name = GetElectrode() vCSS = VoltageClampStimulusSeries('test_vCSS', list(), electrode_name, 1.0, timestamps=list()) self.assertEqual(vCSS.name, 'test_vCSS') self.assertEqual(vCSS.unit, 'volts') self.assertEqual(vCSS.electrode, electrode_name) def test_unit_warning(self): electrode_name = GetElectrode() msg = "Unit 'unit' for VoltageClampStimulusSeries 'test_vCSS' is ignored and will be set " \ "to 'volts' as per NWB 2.1.0." with self.assertWarnsWith(UserWarning, msg): vCSS = VoltageClampStimulusSeries('test_vCSS', list(), electrode_name, 1.0, timestamps=list(), unit='unit') self.assertEqual(vCSS.unit, 'volts') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_icephys_metadata_tables.py0000644000175100001730000020223414467767506022677 0ustar00runnerdocker""" Module for testing of the intracellular electrophysiology experiment metadata tables originally created as part of the ndx-icephys-meta extension. These are tested in this separate module to avoid crowding of the main test_icephys test module and to allow us to test the main experiment metadata structures separately. """ import numpy as np from datetime import datetime from dateutil.tz import tzlocal from pandas.testing import assert_frame_equal from numpy.testing import assert_array_equal import warnings import h5py from pynwb.testing import TestCase, remove_test_file, create_icephys_stimulus_and_response from pynwb.file import NWBFile from pynwb.icephys import ( VoltageClampStimulusSeries, VoltageClampSeries, CurrentClampStimulusSeries, IZeroClampSeries, SimultaneousRecordingsTable, SequentialRecordingsTable, RepetitionsTable, ExperimentalConditionsTable, IntracellularElectrode, CurrentClampSeries, IntracellularRecordingsTable ) from pynwb.device import Device from pynwb.base import TimeSeriesReferenceVectorData from pynwb import NWBHDF5IO from hdmf.utils import docval, popargs class ICEphysMetaTestBase(TestCase): """ Base helper class for setting up tests for the ndx-icephys-meta extension. """ def setUp(self): # Create an example nwbfile with a device, intracellular electrode, stimulus, and response self.nwbfile = NWBFile( session_description='my first synthetic recording', identifier='EXAMPLE_ID', session_start_time=datetime.now(tzlocal()), experimenter='Dr. Bilbo Baggins', lab='Bag End Laboratory', institution='University of Middle Earth at the Shire', experiment_description='I went on an adventure with thirteen dwarves to reclaim vast treasures.', session_id='LONELYMTN' ) self.device = self.nwbfile.create_device(name='Heka ITC-1600') self.electrode = self.nwbfile.create_icephys_electrode( name="elec0", description='a mock intracellular electrode', device=self.device ) self.stimulus = VoltageClampStimulusSeries( name="ccss", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=self.electrode, gain=0.02, sweep_number=np.uint64(15) ) self.nwbfile.add_stimulus(self.stimulus) self.response = VoltageClampSeries( name='vcs', data=[0.1, 0.2, 0.3, 0.4, 0.5], conversion=1e-12, resolution=np.nan, starting_time=123.6, rate=20e3, electrode=self.electrode, gain=0.02, capacitance_slow=100e-12, resistance_comp_correction=70.0, sweep_number=np.uint64(15) ) self.nwbfile.add_acquisition(self.response) self.path = 'test_icephys_meta_intracellularrecording.h5' def tearDown(self): remove_test_file(self.path) @docval({'name': 'ir', 'type': IntracellularRecordingsTable, 'doc': 'Intracellular recording to be added to the file before write', 'default': None}, {'name': 'sw', 'type': SimultaneousRecordingsTable, 'doc': 'SimultaneousRecordingsTable table to be added to the file before write', 'default': None}, {'name': 'sws', 'type': SequentialRecordingsTable, 'doc': 'SequentialRecordingsTable table to be added to the file before write', 'default': None}, {'name': 'repetitions', 'type': RepetitionsTable, 'doc': 'RepetitionsTable table to be added to the file before write', 'default': None}, {'name': 'cond', 'type': ExperimentalConditionsTable, 'doc': 'ExperimentalConditionsTable table to be added to the file before write', 'default': None}) def write_test_helper(self, **kwargs): """ Internal helper function to roundtrip an ICEphys file with the given set of ICEphys tables """ ir, sw, sws, repetitions, cond = popargs('ir', 'sw', 'sws', 'repetitions', 'cond', kwargs) if ir is not None: self.nwbfile.intracellular_recordings = ir if sw is not None: self.nwbfile.icephys_simultaneous_recordings = sw if sws is not None: self.nwbfile.icephys_sequential_recordings = sws if repetitions is not None: self.nwbfile.icephys_repetitions = repetitions if cond is not None: self.nwbfile.icephys_experimental_conditions = cond # Write our test file with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile) # Test that we can read the file with NWBHDF5IO(self.path, 'r') as io: infile = io.read() if ir is not None: in_ir = infile.intracellular_recordings self.assertIsNotNone(in_ir) to_dataframe_kwargs = dict(electrode_refs_as_objectids=True, stimulus_refs_as_objectids=True, response_refs_as_objectids=True) assert_frame_equal(ir.to_dataframe(**to_dataframe_kwargs), in_ir.to_dataframe(**to_dataframe_kwargs)) if sw is not None: in_sw = infile.icephys_simultaneous_recordings self.assertIsNotNone(in_sw) self.assertListEqual(in_sw['recordings'].target.data[:].tolist(), sw['recordings'].target.data[:]) self.assertEqual(in_sw['recordings'].target.table.object_id, sw['recordings'].target.table.object_id) if sws is not None: in_sws = infile.icephys_sequential_recordings self.assertIsNotNone(in_sws) self.assertListEqual(in_sws['simultaneous_recordings'].target.data[:].tolist(), sws['simultaneous_recordings'].target.data[:]) self.assertEqual(in_sws['simultaneous_recordings'].target.table.object_id, sws['simultaneous_recordings'].target.table.object_id) if repetitions is not None: in_repetitions = infile.icephys_repetitions self.assertIsNotNone(in_repetitions) self.assertListEqual(in_repetitions['sequential_recordings'].target.data[:].tolist(), repetitions['sequential_recordings'].target.data[:]) self.assertEqual(in_repetitions['sequential_recordings'].target.table.object_id, repetitions['sequential_recordings'].target.table.object_id) if cond is not None: in_cond = infile.icephys_experimental_conditions self.assertIsNotNone(in_cond) self.assertListEqual(in_cond['repetitions'].target.data[:].tolist(), cond['repetitions'].target.data[:]) self.assertEqual(in_cond['repetitions'].target.table.object_id, cond['repetitions'].target.table.object_id) class IntracellularElectrodesTableTests(TestCase): """ The IntracellularElectrodesTable is covered by the IntracellularRecordingsTableTests as this table is part of that table. """ pass class IntracellularStimuliTableTests(TestCase): """ The IntracellularStimuliTable is covered by the IntracellularRecordingsTableTests as this table is part of that table. """ pass class IntracellularResponsesTableTests(TestCase): """ The IntracellularResponsesTable is covered by the IntracellularRecordingsTableTests as this table is part of that table. """ pass class IntracellularRecordingsTableTests(ICEphysMetaTestBase): """ Class for testing the IntracellularRecordingsTable Container """ def test_init(self): ret = IntracellularRecordingsTable() self.assertEqual(ret.name, 'intracellular_recordings') def test_add_row(self): # Add a row to our IR table ir = IntracellularRecordingsTable() row_index = ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) # Test that we get the correct row index back self.assertEqual(row_index, 0) # Read our first (and only) row and assert that it is correct res = ir[0] # Confirm that slicing one row give the same result as converting the whole table, which has only one row assert_frame_equal(ir.to_dataframe(), res) # Check the row id self.assertEqual(res.index[0], 10) # Check electrodes self.assertIs(res[('electrodes', 'electrode')].iloc[0], self.electrode) # Check the stimulus self.assertTupleEqual(res[('stimuli', 'stimulus')].iloc[0], (0, 5, self.stimulus)) # Check the response self.assertTupleEqual(res[('responses', 'response')].iloc[0], (0, 5, self.response)) # Test writing out ir table self.write_test_helper(ir) def test_add_row_incompatible_types(self): # Add a row that mixes CurrentClamp and VoltageClamp data sweep_number = 15 local_stimulus = CurrentClampStimulusSeries( name="ccss_"+str(sweep_number), data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=self.electrode, gain=0.1, sweep_number=np.uint64(sweep_number) ) ir = IntracellularRecordingsTable() with self.assertRaises(ValueError): _ = ir.add_recording( electrode=self.electrode, stimulus=local_stimulus, response=self.response, id=np.int64(10) ) def test_error_if_IZeroClampSeries_with_stimulus(self): local_response = IZeroClampSeries( name="ccss", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=self.electrode, gain=0.02, sweep_number=np.uint64(100000) ) ir = IntracellularRecordingsTable() with self.assertRaises(ValueError): _ = ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=local_response, id=np.int64(10) ) def test_noerror_if_IZeroClampSeries(self): local_response = IZeroClampSeries( name="ccss", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=self.electrode, gain=0.02, sweep_number=np.uint64(100000) ) ir = IntracellularRecordingsTable() try: _ = ir.add_recording( electrode=self.electrode, response=local_response, id=np.int64(10) ) except ValueError as e: self.fail("Adding IZeroClampSeries falsely resulted in error" + str(e)) def test_inconsistent_PatchClampSeries(self): local_electrode = self.nwbfile.create_icephys_electrode( name="elec1", description='a mock intracellular electrode', device=self.device ) local_stimulus = VoltageClampStimulusSeries( name="ccss", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=local_electrode, gain=0.02, sweep_number=np.uint64(100000) ) ir = IntracellularRecordingsTable() with self.assertRaises(ValueError): _ = ir.add_recording( electrode=self.electrode, stimulus=local_stimulus, response=self.response, id=np.int64(10) ) def test_add_row_no_response(self): ir = IntracellularRecordingsTable() row_index = ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=None, id=np.int64(10) ) res = ir[0] # Check the ID self.assertEqual(row_index, 0) self.assertEqual(res.index[0], 10) # Check the row id self.assertEqual(res.index[0], 10) # Check electrodes self.assertIs(res[('electrodes', 'electrode')].iloc[0], self.electrode) # Check the stimulus self.assertTupleEqual(res[('stimuli', 'stimulus')].iloc[0], (0, 5, self.stimulus)) # Check the response self.assertTrue(isinstance(res[('responses', 'response')].iloc[0], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE)) # Test writing out ir table self.write_test_helper(ir) def test_add_row_no_stimulus(self): ir = IntracellularRecordingsTable() row_index = ir.add_recording( electrode=self.electrode, stimulus=None, response=self.response, id=np.int64(10) ) res = ir[0] # Check the ID self.assertEqual(row_index, 0) self.assertEqual(res.index[0], 10) # Check the row id self.assertEqual(res.index[0], 10) # Check electrodes self.assertIs(res[('electrodes', 'electrode')].iloc[0], self.electrode) # Check the stimulus self.assertTrue(isinstance(res[('stimuli', 'stimulus')].iloc[0], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE)) # Check the response self.assertTupleEqual(res[('responses', 'response')].iloc[0], (0, 5, self.response)) # Test writing out ir table self.write_test_helper(ir) def test_add_row_check_start_index_and_index_count_are_fixed(self): # Make sure -1 values are converted ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, stimulus_start_index=-1, # assert this is fixed to 0 stimulus_index_count=-1, # assert this is fixed to len(stimulus) response=None, response_start_index=0, # assert this is fixed to -1 response_index_count=10, # assert this is fixed to -1 id=np.int64(10) ) res = ir[0] self.assertTupleEqual(res[('stimuli', 'stimulus')].iloc[0], (0, len(self.stimulus.data), self.stimulus)) self.assertTrue(isinstance(res[('responses', 'response')].iloc[0], TimeSeriesReferenceVectorData.TIME_SERIES_REFERENCE_TUPLE)) # Make sure single -1 values are converted ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, stimulus_start_index=2, id=np.int64(10) ) res = ir[0] self.assertTupleEqual(res[('stimuli', 'stimulus')].iloc[0], (2, len(self.stimulus.data)-2, self.stimulus)) # Make sure single -1 values are converted ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, stimulus_index_count=2, id=np.int64(10) ) res = ir[0] self.assertTupleEqual(res[('stimuli', 'stimulus')].iloc[0], (0, 2, self.stimulus)) def test_add_row_index_out_of_range(self): # Stimulus/Response start_index to large with self.assertRaises(IndexError): ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, stimulus_start_index=10, response=self.response, id=np.int64(10) ) with self.assertRaises(IndexError): ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response_start_index=10, response=self.response, id=np.int64(10) ) # Stimulus/Response index count too large with self.assertRaises(IndexError): ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, stimulus_index_count=10, response=self.response, id=np.int64(10) ) with self.assertRaises(IndexError): ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response_index_count=10, response=self.response, id=np.int64(10) ) # Stimulus/Response start+count combination too large with self.assertRaises(IndexError): ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, stimulus_start_index=3, stimulus_index_count=4, response=self.response, id=np.int64(10) ) with self.assertRaises(IndexError): ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response_start_index=3, response_index_count=4, response=self.response, id=np.int64(10) ) def test_add_row_no_stimulus_and_response(self): with self.assertRaises(ValueError): ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=None, response=None ) def test_add_column(self): ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) ir.add_column(name='test', description='test column', data=np.arange(1)) self.assertTupleEqual(ir.colnames, ('test',)) def test_enforce_unique_id(self): """ Test to ensure that unique ids are enforced on RepetitionsTable table """ ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) with self.assertRaises(ValueError): ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) def test_basic_write(self): """ Populate, write, and read the SimultaneousRecordingsTable container and other required containers """ ir = IntracellularRecordingsTable() row_index = ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) self.assertEqual(row_index, 0) ir.add_column(name='test', description='test column', data=np.arange(1)) self.write_test_helper(ir=ir) def test_to_dataframe(self): # Add the intracelluar recordings # Create a table setup for testing a number of conditions electrode0 = self.electrode electrode1 = self.nwbfile.create_icephys_electrode( name="elec1", description='another mock intracellular electrode', device=self.device ) for sweep_number in range(20): elec = (electrode0 if (sweep_number % 2 == 0) else electrode1) stim, resp = create_icephys_stimulus_and_response(sweep_number=np.uint64(sweep_number), electrode=elec, randomize_data=False) if sweep_number in [0, 10]: # include missing stimuli stim = None self.nwbfile.add_intracellular_recording(electrode=elec, stimulus=stim, response=resp, id=sweep_number) tags_data = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'C3', 'D1', 'D2', 'D3', 'A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'C3', 'D1', 'D2', 'D3'] self.nwbfile.intracellular_recordings.add_column(name='recording_tags', data=tags_data, description='String with a set of recording tags') # Test normal conversion to a dataframe df = self.nwbfile.intracellular_recordings.to_dataframe() expected_cols = [('intracellular_recordings', 'recording_tags'), ('electrodes', 'id'), ('electrodes', 'electrode'), ('stimuli', 'id'), ('stimuli', 'stimulus'), ('responses', 'id'), ('responses', 'response')] self.assertListEqual(df.columns.to_list(), expected_cols) self.assertListEqual(df[('intracellular_recordings', 'recording_tags')].to_list(), tags_data) # Test conversion with ignore category ids set df = self.nwbfile.intracellular_recordings.to_dataframe(ignore_category_ids=True) expected_cols_no_ids = [('intracellular_recordings', 'recording_tags'), ('electrodes', 'electrode'), ('stimuli', 'stimulus'), ('responses', 'response')] self.assertListEqual(df.columns.to_list(), expected_cols_no_ids) # Test conversion with stimulus_refs_as_objectids df = self.nwbfile.intracellular_recordings.to_dataframe(stimulus_refs_as_objectids=True) self.assertListEqual(df.columns.to_list(), expected_cols) expects_stim_col = [e if e[2] is None else (e[0], e[1], e[2].object_id) for e in self.nwbfile.intracellular_recordings[('stimuli', 'stimulus')][:]] self.assertListEqual(df[('stimuli', 'stimulus')].tolist(), expects_stim_col) # Test conversion with response_refs_as_objectids df = self.nwbfile.intracellular_recordings.to_dataframe(response_refs_as_objectids=True) self.assertListEqual(df.columns.to_list(), expected_cols) expects_resp_col = [e if e[2] is None else (e[0], e[1], e[2].object_id) for e in self.nwbfile.intracellular_recordings[('responses', 'response')][:]] self.assertListEqual(df[('responses', 'response')].tolist(), expects_resp_col) # Test conversion with all options enabled df = self.nwbfile.intracellular_recordings.to_dataframe(ignore_category_ids=True, stimulus_refs_as_objectids=True, response_refs_as_objectids=True) self.assertListEqual(df.columns.to_list(), expected_cols_no_ids) self.assertListEqual(df[('stimuli', 'stimulus')].tolist(), expects_stim_col) self.assertListEqual(df[('responses', 'response')].tolist(), expects_resp_col) def test_round_trip_container_no_data(self): """Test read and write the container by itself""" curr = IntracellularRecordingsTable() with NWBHDF5IO(self.path, 'w') as io: io.write(curr) with NWBHDF5IO(self.path, 'r') as io: incon = io.read(skip_version_check=True) self.assertListEqual(incon.categories, curr.categories) for n in curr.categories: # empty columns from file have dtype int64 or float64 but empty in-memory columns have dtype object assert_frame_equal(incon[n], curr[n], check_dtype=False, check_index_type=False) def test_write_with_stimulus_template(self): """ Populate, write, and read the SimultaneousRecordingsTable container and other required containers """ local_nwbfile = NWBFile( session_description='my first synthetic recording', identifier='EXAMPLE_ID', session_start_time=datetime.now(tzlocal()), experimenter='Dr. Bilbo Baggins', lab='Bag End Laboratory', institution='University of Middle Earth at the Shire', experiment_description='I went on an adventure with thirteen dwarves to reclaim vast treasures.', session_id='LONELYMTN' ) # Add a device local_device = local_nwbfile.create_device(name='Heka ITC-1600') local_electrode = local_nwbfile.create_icephys_electrode( name="elec0", description='a mock intracellular electrode', device=local_device ) local_stimulus = VoltageClampStimulusSeries( name="ccss", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=local_electrode, gain=0.02, sweep_number=np.uint64(15) ) local_response = VoltageClampSeries( name='vcs', data=[0.1, 0.2, 0.3, 0.4, 0.5], conversion=1e-12, resolution=np.nan, starting_time=123.6, rate=20e3, electrode=local_electrode, gain=0.02, capacitance_slow=100e-12, resistance_comp_correction=70.0, sweep_number=np.uint64(15) ) local_nwbfile.add_stimulus_template(local_stimulus) row_index = local_nwbfile.add_intracellular_recording( electrode=local_electrode, stimulus=local_stimulus, response=local_response, id=np.int64(10) ) self.assertEqual(row_index, 0) # Write our test file with NWBHDF5IO(self.path, 'w') as io: io.write(local_nwbfile) def test_no_electrode(self): device = Device(name='device_name') elec = IntracellularElectrode( name='test_iS', device=device, description='description', slice='slice', seal='seal', location='location', resistance='resistance', filtering='filtering', initial_access_resistance='initial_access_resistance', cell_id='this_cell', ) cCSS = CurrentClampStimulusSeries( name="test_cCSS", data=np.ones((30,)), electrode=elec, gain=1.0, rate=100_000., ) cCS = CurrentClampSeries( name="test_cCS", data=np.ones((30,)), electrode=elec, gain=1.0, rate=100_000., ) # test retrieve electrode from stimulus (when both stimulus and response are given) itr = IntracellularRecordingsTable() itr.add_recording(stimulus=cCSS, response=cCS) self.assertEqual(itr["electrodes"].values[0], elec) del itr # test retrieve electrode from stimulus (when only stimulus is given) itr = IntracellularRecordingsTable() itr.add_recording(stimulus=cCSS, response=None) self.assertEqual(itr["electrodes"].values[0], elec) del itr # test retrieve electrode from response (when only response is given) itr = IntracellularRecordingsTable() itr.add_recording(stimulus=None, response=cCS) self.assertEqual(itr["electrodes"].values[0], elec) class SimultaneousRecordingsTableTests(ICEphysMetaTestBase): """ Test class for testing the SimultaneousRecordingsTable Container class """ def test_init(self): """ Test __init__ to make sure we can instantiate the SimultaneousRecordingsTable container """ ir = IntracellularRecordingsTable() ret = SimultaneousRecordingsTable(intracellular_recordings_table=ir) self.assertIs(ret.recordings.table, ir) self.assertEqual(ret.name, 'simultaneous_recordings') def test_missing_intracellular_recordings_on_init(self): """ Test that ValueError is raised when intracellular_recordings is missing. This is allowed only on read where the intracellular_recordings table is already set from the file. """ with self.assertRaises(ValueError): _ = SimultaneousRecordingsTable() def test_add_simultaneous_recording(self): """ Populate, write, and read the SimultaneousRecordingsTable container and other required containers """ ir = IntracellularRecordingsTable() row_index = ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) self.assertEqual(row_index, 0) self.assertEqual(len(ir), 1) sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) row_index = sw.add_simultaneous_recording(recordings=[row_index], id=100) self.assertEqual(row_index, 0) self.assertListEqual(sw.id[:], [100]) self.assertListEqual(sw['recordings'].data, [1]) self.assertListEqual(sw['recordings'].target.data[:], [0]) def test_basic_write(self): """ Populate, write, and read the SimultaneousRecordingsTable container and other required containers """ ir = IntracellularRecordingsTable() row_index = ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) self.assertEqual(row_index, 0) self.assertEqual(len(ir), 1) sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) row_index = sw.add_simultaneous_recording(recordings=[row_index]) self.assertEqual(row_index, 0) self.write_test_helper(ir=ir, sw=sw) def test_enforce_unique_id(self): """ Test to ensure that unique ids are enforced on RepetitionsTable table """ ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) sw.add_simultaneous_recording(recordings=[0], id=np.int64(10)) with self.assertRaises(ValueError): sw.add_simultaneous_recording(recordings=[0], id=np.int64(10)) class SequentialRecordingsTableTests(ICEphysMetaTestBase): """ Test class for testing the SequentialRecordingsTable Container class """ def test_init(self): """ Test __init__ to make sure we can instantiate the SequentialRecordingsTable container """ ir = IntracellularRecordingsTable() sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) ret = SequentialRecordingsTable(simultaneous_recordings_table=sw) self.assertIs(ret.simultaneous_recordings.table, sw) self.assertEqual(ret.name, 'sequential_recordings') def test_missing_simultaneous_recordings_on_init(self): """ Test that ValueError is raised when simultaneous_recordings is missing. This is allowed only on read where the simultaneous_recordings table is already set from the file. """ with self.assertRaises(ValueError): _ = SequentialRecordingsTable() def test_basic_write(self): """ Populate, write, and read the SequentialRecordingsTable container and other required containers """ ir = IntracellularRecordingsTable() row_index = ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) self.assertEqual(row_index, 0) sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) row_index = sw.add_simultaneous_recording(recordings=[0]) self.assertEqual(row_index, 0) sws = SequentialRecordingsTable(sw) row_index = sws.add_sequential_recording(simultaneous_recordings=[0, ], stimulus_type='MyStimStype') self.assertEqual(row_index, 0) self.write_test_helper(ir=ir, sw=sw, sws=sws) def test_enforce_unique_id(self): """ Test to ensure that unique ids are enforced on RepetitionsTable table """ ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) sw.add_simultaneous_recording(recordings=[0]) sws = SequentialRecordingsTable(sw) sws.add_sequential_recording(simultaneous_recordings=[0, ], id=np.int64(10), stimulus_type='MyStimStype') with self.assertRaises(ValueError): sws.add_sequential_recording(simultaneous_recordings=[0, ], id=np.int64(10), stimulus_type='MyStimStype') class RepetitionsTableTests(ICEphysMetaTestBase): """ Test class for testing the RepetitionsTable Container class """ def test_init(self): """ Test __init__ to make sure we can instantiate the RepetitionsTable container """ ir = IntracellularRecordingsTable() sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) sws = SequentialRecordingsTable(simultaneous_recordings_table=sw) ret = RepetitionsTable(sequential_recordings_table=sws) self.assertIs(ret.sequential_recordings.table, sws) self.assertEqual(ret.name, 'repetitions') def test_missing_sequential_recordings_on_init(self): """ Test that ValueError is raised when sequential_recordings is missing. This is allowed only on read where the sequential_recordings table is already set from the file. """ with self.assertRaises(ValueError): _ = RepetitionsTable() def test_basic_write(self): """ Populate, write, and read the RepetitionsTable container and other required containers """ ir = IntracellularRecordingsTable() row_index = ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) self.assertEqual(row_index, 0) sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) row_index = sw.add_simultaneous_recording(recordings=[0]) self.assertEqual(row_index, 0) sws = SequentialRecordingsTable(sw) row_index = sws.add_sequential_recording(simultaneous_recordings=[0, ], stimulus_type='MyStimStype') self.assertEqual(row_index, 0) repetitions = RepetitionsTable(sequential_recordings_table=sws) repetitions.add_repetition(sequential_recordings=[0, ]) self.write_test_helper(ir=ir, sw=sw, sws=sws, repetitions=repetitions) def test_enforce_unique_id(self): """ Test to ensure that unique ids are enforced on RepetitionsTable table """ ir = IntracellularRecordingsTable() ir.add_recording( electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10) ) sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) sw.add_simultaneous_recording(recordings=[0]) sws = SequentialRecordingsTable(sw) sws.add_sequential_recording(simultaneous_recordings=[0, ], stimulus_type='MyStimStype') repetitions = RepetitionsTable(sequential_recordings_table=sws) repetitions.add_repetition(sequential_recordings=[0, ], id=np.int64(10)) with self.assertRaises(ValueError): repetitions.add_repetition(sequential_recordings=[0, ], id=np.int64(10)) class ExperimentalConditionsTableTests(ICEphysMetaTestBase): """ Test class for testing the ExperimentalConditionsTable Container class """ def test_init(self): """ Test __init__ to make sure we can instantiate the ExperimentalConditionsTable container """ ir = IntracellularRecordingsTable() sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) sws = SequentialRecordingsTable(simultaneous_recordings_table=sw) repetitions = RepetitionsTable(sequential_recordings_table=sws) ret = ExperimentalConditionsTable(repetitions_table=repetitions) self.assertIs(ret.repetitions.table, repetitions) self.assertEqual(ret.name, 'experimental_conditions') def test_missing_repetitions_on_init(self): """ Test that ValueError is raised when repetitions is missing. This is allowed only on read where the repetitions table is already set from the file. """ with self.assertRaises(ValueError): _ = ExperimentalConditionsTable() def test_basic_write(self): """ Populate, write, and read the ExperimentalConditionsTable container and other required containers """ ir = IntracellularRecordingsTable() row_index = ir.add_recording(electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10)) self.assertEqual(row_index, 0) sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) row_index = sw.add_simultaneous_recording(recordings=[0]) self.assertEqual(row_index, 0) sws = SequentialRecordingsTable(sw) row_index = sws.add_sequential_recording(simultaneous_recordings=[0, ], stimulus_type='MyStimStype') self.assertEqual(row_index, 0) repetitions = RepetitionsTable(sequential_recordings_table=sws) row_index = repetitions.add_repetition(sequential_recordings=[0, ]) self.assertEqual(row_index, 0) cond = ExperimentalConditionsTable(repetitions_table=repetitions) row_index = cond.add_experimental_condition(repetitions=[0, ]) self.assertEqual(row_index, 0) self.write_test_helper(ir=ir, sw=sw, sws=sws, repetitions=repetitions, cond=cond) def test_enforce_unique_id(self): """ Test to ensure that unique ids are enforced on RepetitionsTable table """ ir = IntracellularRecordingsTable() ir.add_recording(electrode=self.electrode, stimulus=self.stimulus, response=self.response, id=np.int64(10)) sw = SimultaneousRecordingsTable(intracellular_recordings_table=ir) sw.add_simultaneous_recording(recordings=[0]) sws = SequentialRecordingsTable(sw) sws.add_sequential_recording(simultaneous_recordings=[0, ], stimulus_type='MyStimStype') repetitions = RepetitionsTable(sequential_recordings_table=sws) repetitions.add_repetition(sequential_recordings=[0, ]) cond = ExperimentalConditionsTable(repetitions_table=repetitions) cond.add_experimental_condition(repetitions=[0, ], id=np.int64(10)) with self.assertRaises(ValueError): cond.add_experimental_condition(repetitions=[0, ], id=np.int64(10)) class NWBFileTests(TestCase): """ Test class for testing the NWBFileTests Container class """ def setUp(self): warnings.simplefilter("always") # Trigger all warnings self.path = 'test_icephys_meta_intracellularrecording.h5' def tearDown(self): remove_test_file(self.path) def __get_icephysfile(self): """ Create a dummy NWBFile instance """ icefile = NWBFile( session_description='my first synthetic recording', identifier='EXAMPLE_ID', session_start_time=datetime.now(tzlocal()) ) return icefile def __add_device(self, icefile): return icefile.create_device(name='Heka ITC-1600') def __add_electrode(self, icefile, device): return icefile.create_icephys_electrode(name="elec0", description='a mock intracellular electrode', device=device) def __get_stimulus(self, electrode): """ Create a dummy VoltageClampStimulusSeries """ return VoltageClampStimulusSeries( name="ccss", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=electrode, gain=0.02, sweep_number=np.uint64(15) ) def __get_response(self, electrode): """ Create a dummy VoltageClampSeries """ return VoltageClampSeries( name='vcs', data=[0.1, 0.2, 0.3, 0.4, 0.5], conversion=1e-12, resolution=np.nan, starting_time=123.6, rate=20e3, electrode=electrode, gain=0.02, capacitance_slow=100e-12, resistance_comp_correction=70.0, sweep_number=np.uint64(15) ) def test_deprecate_simultaneous_recordings_on_add_stimulus(self): """ Test that warnings are raised if the user tries to use a simultaneous_recordings table """ nwbfile = self.__get_icephysfile() device = self.__add_device(nwbfile) electrode = self.__add_electrode(nwbfile, device) stimulus = self.__get_stimulus(electrode=electrode) response = self.__get_response(electrode=electrode) # Make sure we warn if sweeptable is added on add_stimulus with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") # Trigger all warnings nwbfile.add_stimulus(stimulus, use_sweep_table=True) self.assertEqual(len(w), 1) assert issubclass(w[-1].category, DeprecationWarning) # make sure we don't trigger the same deprecation warning twice nwbfile.add_acquisition(response, use_sweep_table=True) self.assertEqual(len(w), 1) def test_deprecate_sweeptable_on_add_stimulus_template(self): """ Make sure we warn when using the sweep-table """ nwbfile = self.__get_icephysfile() local_electrode = nwbfile.create_icephys_electrode( name="elec0", description='a mock intracellular electrode', device=nwbfile.create_device(name='Heka ITC-1600') ) local_stimulus = VoltageClampStimulusSeries( name="ccss", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=local_electrode, gain=0.02, sweep_number=np.uint64(15) ) local_stimulus2 = VoltageClampStimulusSeries( name="ccss2", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=local_electrode, gain=0.02, sweep_number=np.uint64(15) ) with warnings.catch_warnings(record=True) as w: nwbfile.add_stimulus_template(local_stimulus, use_sweep_table=True) self.assertEqual(len(w), 1) assert issubclass(w[-1].category, DeprecationWarning) self.assertEqual(str(w[-1].message), "Use of SweepTable is deprecated. Use the IntracellularRecordingsTable " "instead. See also the NWBFile.add_intracellular_recordings function.") # make sure we don't trigger the same deprecation warning twice nwbfile.add_stimulus_template(local_stimulus2, use_sweep_table=True) self.assertEqual(len(w), 1) def test_deprecate_sweepstable_on_add_acquistion(self): """ Test that warnings are raised if the user tries to use a sweeps table """ nwbfile = self.__get_icephysfile() device = self.__add_device(nwbfile) electrode = self.__add_electrode(nwbfile, device) stimulus = self.__get_stimulus(electrode=electrode) response = self.__get_response(electrode=electrode) # Make sure we warn if sweeptable is added on add_stimulus with warnings.catch_warnings(record=True) as w: nwbfile.add_acquisition(response, use_sweep_table=True) self.assertEqual(len(w), 1) assert issubclass(w[-1].category, DeprecationWarning) self.assertEqual(str(w[-1].message), "Use of SweepTable is deprecated. Use the IntracellularRecordingsTable " "instead. See also the NWBFile.add_intracellular_recordings function.") # make sure we don't trigger the same deprecation warning twice nwbfile.add_stimulus(stimulus, use_sweep_table=True) self.assertEqual(len(w), 1) def test_deprecate_sweepstable_on_init(self): """ Test that warnings are raised if the user tries to use a sweeps table """ from pynwb.icephys import SweepTable with warnings.catch_warnings(record=True) as w: nwbfile = NWBFile( session_description='my first synthetic recording', identifier='EXAMPLE_ID', session_start_time=datetime.now(tzlocal()), sweep_table=SweepTable() ) device = self.__add_device(nwbfile) electrode = self.__add_electrode(nwbfile, device) stimulus = self.__get_stimulus(electrode=electrode) self.assertEqual(len(w), 1) assert issubclass(w[-1].category, DeprecationWarning) # make sure we don't trigger the same deprecation warning twice nwbfile.add_stimulus(stimulus, use_sweep_table=True) self.assertEqual(len(w), 1) def test_deprectation_icephys_filtering_on_init(self): with warnings.catch_warnings(record=True) as w: nwbfile = NWBFile( session_description='my first synthetic recording', identifier='EXAMPLE_ID', session_start_time=datetime.now(tzlocal()), icephys_filtering='test filtering' ) assert issubclass(w[-1].category, DeprecationWarning) self.assertEqual(nwbfile.icephys_filtering, 'test filtering') def test_icephys_filtering_roundtrip(self): # create the base file nwbfile = NWBFile( session_description='my first synthetic recording', identifier='EXAMPLE_ID', session_start_time=datetime.now(tzlocal()) ) # set the icephys_filtering attribute and make sure we get a deprecation warning with warnings.catch_warnings(record=True) as w: nwbfile.icephys_filtering = 'test filtering' assert issubclass(w[-1].category, DeprecationWarning) # write the test fil with NWBHDF5IO(self.path, 'w') as io: io.write(nwbfile) # read the test file and confirm icephys_filtering has been written with NWBHDF5IO(self.path, 'r') as io: with warnings.catch_warnings(record=True) as w: infile = io.read() self.assertEqual(len(w), 1) # make sure a warning is being raised assert issubclass(w[0].category, DeprecationWarning) # make sure it is a deprecation warning self.assertEqual(infile.icephys_filtering, 'test filtering') # make sure the value is set def test_get_icephys_meta_parent_table(self): """ Create the table hierarchy step-by-step and check that as we add tables the get_icephys_meta_parent_table returns the expected top table """ local_nwbfile = NWBFile( session_description='my first synthetic recording', identifier='EXAMPLE_ID', session_start_time=datetime.now(tzlocal()) ) # Add a device local_device = local_nwbfile.create_device(name='Heka ITC-1600') local_electrode = local_nwbfile.create_icephys_electrode( name="elec0", description='a mock intracellular electrode', device=local_device ) local_stimulus = VoltageClampStimulusSeries( name="ccss", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=local_electrode, gain=0.02, sweep_number=np.uint64(15) ) local_response = VoltageClampSeries( name='vcs', data=[0.1, 0.2, 0.3, 0.4, 0.5], conversion=1e-12, resolution=np.nan, starting_time=123.6, rate=20e3, electrode=local_electrode, gain=0.02, capacitance_slow=100e-12, resistance_comp_correction=70.0, sweep_number=np.uint64(15) ) local_nwbfile.add_stimulus_template(local_stimulus) # Check that none of the table exist yet self.assertIsNone(local_nwbfile.get_icephys_meta_parent_table()) # Add a recording and confirm that intracellular_recordings is the top table _ = local_nwbfile.add_intracellular_recording( electrode=local_electrode, stimulus=local_stimulus, response=local_response, id=np.int64(10) ) self.assertIsInstance(local_nwbfile.get_icephys_meta_parent_table(), IntracellularRecordingsTable) # Add a sweep and check that the simultaneous_recordings table is the top table _ = local_nwbfile.add_icephys_simultaneous_recording(recordings=[0]) self.assertIsInstance(local_nwbfile.get_icephys_meta_parent_table(), SimultaneousRecordingsTable) # Add a sweep_sequence and check that it is now our top table _ = local_nwbfile.add_icephys_sequential_recording(simultaneous_recordings=[0], stimulus_type="MyStimulusType") self.assertIsInstance(local_nwbfile.get_icephys_meta_parent_table(), SequentialRecordingsTable) # Add a repetition and check that it is now our top table _ = local_nwbfile.add_icephys_repetition(sequential_recordings=[0]) self.assertIsInstance(local_nwbfile.get_icephys_meta_parent_table(), RepetitionsTable) # Add a condition and check that it is now our top table _ = local_nwbfile.add_icephys_experimental_condition(repetitions=[0]) self.assertIsInstance(local_nwbfile.get_icephys_meta_parent_table(), ExperimentalConditionsTable) def test_add_icephys_meta_full_roundtrip(self): """ This test adds all data and then constructs step-by-step the full table structure Returns: """ #################################### # Create our file and timeseries ################################### nwbfile = self.__get_icephysfile() device = self.__add_device(nwbfile) electrode = self.__add_electrode(nwbfile, device) # Add the data using standard methods from NWBFile stimulus = self.__get_stimulus(electrode=electrode) nwbfile.add_stimulus(stimulus) # Check that the deprecated sweep table has indeed not been created self.assertIsNone(nwbfile.sweep_table) response = self.__get_response(electrode=electrode) nwbfile.add_acquisition(response) # Check that the deprecated sweep table has indeed not been created self.assertIsNone(nwbfile.sweep_table) ############################################# # Test adding IntracellularRecordingsTable ############################################# # Check that our IntracellularRecordingsTable table does not yet exist self.assertIsNone(nwbfile.intracellular_recordings) # Add an intracellular recording intracellular_recording_ids = [np.int64(10), np.int64(11)] nwbfile.add_intracellular_recording( electrode=electrode, stimulus=stimulus, response=response, id=intracellular_recording_ids[0] ) nwbfile.add_intracellular_recording( electrode=electrode, stimulus=stimulus, response=response, id=intracellular_recording_ids[1] ) # Check that the table has been created self.assertIsNotNone(nwbfile.intracellular_recordings) # Check that the values in our row are correct self.assertEqual(len(nwbfile.intracellular_recordings), 2) res = nwbfile.intracellular_recordings[0] # Check the ID self.assertEqual(res.index[0], intracellular_recording_ids[0]) # Check electrodes self.assertIs(res[('electrodes', 'electrode')].iloc[0], electrode) # Check the stimulus self.assertTupleEqual(res[('stimuli', 'stimulus')].iloc[0], (0, 5, stimulus)) # Check the response self.assertTupleEqual(res[('responses', 'response')].iloc[0], (0, 5, response)) ############################################# # Test adding SimultaneousRecordingsTable ############################################# # Confirm that our SimultaneousRecordingsTable table does not yet exist self.assertIsNone(nwbfile.icephys_simultaneous_recordings) # Add a sweep simultaneous_recordings_id = np.int64(12) recordings_indices = [0, 1] nwbfile.add_icephys_simultaneous_recording(recordings=recordings_indices, id=simultaneous_recordings_id) # Check that the SimultaneousRecordingsTable table has been added self.assertIsNotNone(nwbfile.icephys_simultaneous_recordings) # Check that the values for our icephys_simultaneous_recordings table are correct self.assertListEqual(nwbfile.icephys_simultaneous_recordings.id[:], [simultaneous_recordings_id]) self.assertListEqual(nwbfile.icephys_simultaneous_recordings['recordings'].data, [2]) self.assertListEqual(nwbfile.icephys_simultaneous_recordings['recordings'].target.data[:], [0, 1]) res = nwbfile.icephys_simultaneous_recordings[0] # check the id value self.assertEqual(res.index[0], simultaneous_recordings_id) # Check that our simultaneous recording contains 2 IntracellularRecording assert_array_equal(res.loc[simultaneous_recordings_id]['recordings'], recordings_indices) ############################################# # Test adding a SweepSequence ############################################# # Confirm that our SequentialRecordingsTable table does not yet exist self.assertIsNone(nwbfile.icephys_sequential_recordings) # Add a sweep sequential_recording_id = np.int64(15) simultaneous_recordings_indices = [0] nwbfile.add_icephys_sequential_recording(simultaneous_recordings=simultaneous_recordings_indices, id=sequential_recording_id, stimulus_type="MyStimulusType") # Check that the SimultaneousRecordingsTable table has been added self.assertIsNotNone(nwbfile.icephys_sequential_recordings) # Check that the values for our SimultaneousRecordingsTable table are correct res = nwbfile.icephys_sequential_recordings[0] # check the id value self.assertEqual(res.index[0], sequential_recording_id) # Check that our sequential recording contains 1 simultaneous recording assert_array_equal(res.loc[sequential_recording_id]['simultaneous_recordings'], simultaneous_recordings_indices) ############################################# # Test adding a Run ############################################# # Confirm that our RepetitionsTable table does not yet exist self.assertIsNone(nwbfile.icephys_repetitions) # Add a repetition sequential_recordings_indices = [0] repetition_id = np.int64(17) nwbfile.add_icephys_repetition(sequential_recordings=sequential_recordings_indices, id=repetition_id) # Check that the SimultaneousRecordingsTable table has been added self.assertIsNotNone(nwbfile.icephys_repetitions) # Check that the values for our RepetitionsTable table are correct res = nwbfile.icephys_repetitions[0] # check the id value self.assertEqual(res.index[0], repetition_id) # Check that our repetition contains 1 SweepSequence assert_array_equal(res.loc[repetition_id]['sequential_recordings'], sequential_recordings_indices) ############################################# # Test adding a Condition ############################################# # Confirm that our RepetitionsTable table does not yet exist self.assertIsNone(nwbfile.icephys_experimental_conditions) # Add a condition repetitions_indices = [0] experiment_id = np.int64(19) nwbfile.add_icephys_experimental_condition(repetitions=repetitions_indices, id=experiment_id) # Check that the ExperimentalConditionsTable table has been added self.assertIsNotNone(nwbfile.icephys_experimental_conditions) # Check that the values for our ExperimentalConditionsTable table are correct res = nwbfile.icephys_experimental_conditions[0] # check the id value self.assertEqual(res.index[0], experiment_id) # Check that our repetition contains 1 repetition assert_array_equal(res.loc[experiment_id]['repetitions'], repetitions_indices) ############################################# # Test writing the file to disk ############################################# # Write our file to disk # Write our test file with NWBHDF5IO(self.path, 'w') as nwbio: # # Uncomment the following lines to enable profiling for write # import cProfile, pstats, io # from pstats import SortKey # pr = cProfile.Profile() # pr.enable() nwbio.write(nwbfile) # pr.disable() # s = io.StringIO() # sortby = SortKey.CUMULATIVE # ps = pstats.Stats(pr, stream=s).sort_stats(sortby) # ps.print_stats() # print(s.getvalue()) ################################################################# # Confirm that the low-level data has been written as expected # using h5py to confirm all id values. We do this before we try # to read the file back to confirm that data is correct on disk. ################################################################# with h5py.File(self.path, 'r') as io: assert_array_equal(io['/general']['intracellular_ephys']['intracellular_recordings']['id'][:], intracellular_recording_ids) default_ids = [0, 1] assert_array_equal(io['/general']['intracellular_ephys']['intracellular_recordings']['electrodes']['id'][:], default_ids) assert_array_equal(io['/general']['intracellular_ephys']['intracellular_recordings']['stimuli']['id'][:], default_ids) assert_array_equal(io['/general']['intracellular_ephys']['intracellular_recordings']['responses']['id'][:], default_ids) assert_array_equal(io['/general']['intracellular_ephys']['simultaneous_recordings']['id'][:], [simultaneous_recordings_id, ]) assert_array_equal(io['/general']['intracellular_ephys']['sequential_recordings']['id'][:], [sequential_recording_id, ]) assert_array_equal(io['/general']['intracellular_ephys']['repetitions']['id'][:], [repetition_id, ]) assert_array_equal(io['/general']['intracellular_ephys']['experimental_conditions']['id'][:], [experiment_id, ]) ############################################# # Test reading the file back from disk ############################################# with NWBHDF5IO(self.path, 'r') as nwbio: # # Uncomment the following lines to enable profiling for read # import cProfile, pstats, io # from pstats import SortKey # pr = cProfile.Profile() # pr.enable() infile = nwbio.read() # pr.disable() # s = io.StringIO() # sortby = SortKey.CUMULATIVE # ps = pstats.Stats(pr, stream=s).sort_stats(sortby) # ps.print_stats() # print(s.getvalue()) ############################################################################ # Test that the IntracellularRecordingsTable table has been written correctly ############################################################################ self.assertIsNotNone(infile.intracellular_recordings) self.assertEqual(len(infile.intracellular_recordings), 2) res = infile.intracellular_recordings[0] # Check the ID self.assertEqual(res.index[0], 10) # Check the stimulus self.assertEqual(res[('stimuli', 'stimulus')].iloc[0][0], 0) self.assertEqual(res[('stimuli', 'stimulus')].iloc[0][1], 5) self.assertEqual(res[('stimuli', 'stimulus')].iloc[0][2].object_id, stimulus.object_id) # Check the response self.assertEqual(res[('responses', 'response')].iloc[0][0], 0) self.assertEqual(res[('responses', 'response')].iloc[0][1], 5) self.assertEqual(res[('responses', 'response')].iloc[0][2].object_id, nwbfile.get_acquisition('vcs').object_id) # Check the Intracellular electrode self.assertEqual(res[('electrodes', 'electrode')].iloc[0].object_id, electrode.object_id) ############################################################################ # Test that the SimultaneousRecordingsTable table has been written correctly ############################################################################ self.assertIsNotNone(infile.icephys_simultaneous_recordings) self.assertEqual(len(infile.icephys_simultaneous_recordings), 1) res = infile.icephys_simultaneous_recordings[0] # Check the ID and len of the intracellular_recordings column self.assertEqual(res.index[0], simultaneous_recordings_id) assert_array_equal(res.loc[simultaneous_recordings_id]['recordings'], recordings_indices) ############################################################################ # Test that the SequentialRecordingsTable table has been written correctly ############################################################################ self.assertIsNotNone(infile.icephys_sequential_recordings) self.assertEqual(len(infile.icephys_sequential_recordings), 1) res = infile.icephys_sequential_recordings[0] # Check the ID and len of the simultaneous_recordings column self.assertEqual(res.index[0], sequential_recording_id) assert_array_equal(res.loc[sequential_recording_id]['simultaneous_recordings'], simultaneous_recordings_indices) ############################################################################ # Test that the RepetitionsTable table has been written correctly ############################################################################ self.assertIsNotNone(infile.icephys_repetitions) self.assertEqual(len(infile.icephys_repetitions), 1) res = infile.icephys_repetitions[0] # Check the ID and len of the simultaneous_recordings column self.assertEqual(res.index[0], repetition_id) assert_array_equal(res.loc[repetition_id]['sequential_recordings'], sequential_recordings_indices) ############################################################################ # Test that the ExperimentalConditionsTable table has been written correctly ############################################################################ self.assertIsNotNone(infile.icephys_experimental_conditions) self.assertEqual(len(infile.icephys_experimental_conditions), 1) res = infile.icephys_experimental_conditions[0] # Check the ID and len of the simultaneous_recordings column self.assertEqual(res.index[0], experiment_id) assert_array_equal(res.loc[experiment_id]['repetitions'], repetitions_indices) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_image.py0000644000175100001730000003746014467767506017132 0ustar00runnerdockerimport warnings import numpy as np from pynwb import TimeSeries from pynwb.base import Image, Images, ImageReferences from pynwb.device import Device from pynwb.image import ( ImageSeries, IndexSeries, ImageMaskSeries, OpticalSeries, GrayscaleImage, RGBImage, RGBAImage, ) from pynwb.testing import TestCase class ImageSeriesConstructor(TestCase): def test_init(self): dev = Device('test_device') iS = ImageSeries( name='test_iS', unit='unit', external_file=['external_file'], starting_frame=[0], format='external', timestamps=[1., 2., 3.], device=dev, ) self.assertEqual(iS.name, 'test_iS') self.assertEqual(iS.unit, 'unit') self.assertEqual(iS.external_file, ['external_file']) self.assertEqual(iS.starting_frame, [0]) self.assertEqual(iS.format, 'external') self.assertIs(iS.device, dev) # self.assertEqual(iS.bits_per_pixel, np.nan) def test_no_data_no_file(self): msg = "Must supply either external_file or data to ImageSeries 'test_iS'." with self.assertRaisesWith(ValueError, msg): ImageSeries( name='test_iS', unit='unit', rate=2., ) def test_external_file_no_frame(self): iS = ImageSeries( name='test_iS', unit='unit', external_file=['external_file'], format="external", timestamps=[1., 2., 3.] ) self.assertListEqual(iS.starting_frame, [0]) def test_data_no_frame(self): iS = ImageSeries( name='test_iS', unit='unit', data=np.ones((3, 3, 3)), timestamps=[1., 2., 3.] ) self.assertIsNone(iS.starting_frame) def test_data_no_unit(self): msg = "Must supply 'unit' argument when supplying 'data' to ImageSeries 'test_iS'." with self.assertRaisesWith(ValueError, msg): ImageSeries( name='test_iS', data=np.ones((3, 3, 3)), timestamps=list() ) def test_external_file_no_unit(self): iS = ImageSeries( name='test_iS', external_file=['external_file'], format="external", timestamps=list() ) self.assertEqual(iS.unit, ImageSeries.DEFAULT_UNIT) def test_dimension_warning(self): """Test that a warning is raised when the dimensions of the data are not the same as the dimensions of the timestamps.""" msg = ( "ImageSeries 'test_iS': Length of data does not match length of timestamps. Your data may be " "transposed. Time should be on the 0th dimension" ) with self.assertWarnsWith(UserWarning, msg): ImageSeries( name='test_iS', data=np.ones((3, 3, 3)), unit='Frames', timestamps=[1, 2, 3, 4] ) def test_dimension_warning_external_file_with_timestamps(self): """Test that a warning is not raised when external file is used with timestamps.""" with warnings.catch_warnings(record=True) as w: ImageSeries( name='test_iS', external_file=['external_file'], format='external', unit='Frames', starting_frame=[0], timestamps=[1, 2, 3, 4] ) self.assertEqual(w, []) def test_dimension_warning_external_file_with_rate(self): """Test that a warning is not raised when external file is used with rate.""" with warnings.catch_warnings(record=True) as w: ImageSeries( name='test_iS', external_file=['external_file'], format='external', unit='Frames', starting_frame=[0], rate=0.2, ) self.assertEqual(w, []) def test_external_file_with_incorrect_starting_frame(self): """Test that ValueError is raised when the length of starting_frame is not the same as the length of external_file.""" for starting_frame in [None, [0], [1, 2, 3]]: with self.subTest(): msg = ( "ImageSeries 'test_iS': The number of frame indices in " "'starting_frame' should have the same length as 'external_file'." ) with self.assertRaisesWith(ValueError, msg): ImageSeries( name="test_iS", external_file=["external_file", "external_file2"], format="external", unit="n.a.", starting_frame=starting_frame, rate=0.2, ) def test_external_file_with_incorrect_starting_frame_construct_mode(self): """Test that warning is raised when the length of starting_frame is not the same as the length of external_file in case that the ImageSeries in construct mode (i.e., during read).""" for starting_frame in [None, [0], [1, 2, 3]]: with self.subTest(): msg = ( "ImageSeries 'test_iS': The number of frame indices in " "'starting_frame' should have the same length as 'external_file'." ) # Create the image series in construct mode, modelling the behavior # of the ObjectMapper on read while avoiding having to create, write, # and read and entire NWB file obj = ImageSeries.__new__(ImageSeries, container_source=None, parent=None, object_id="test", in_construct_mode=True) with self.assertWarnsWith(warn_type=UserWarning, exc_msg=msg): obj.__init__( name="test_iS", external_file=["external_file", "external_file2"], format="external", unit="n.a.", starting_frame=starting_frame, rate=0.2, ) # Disable construct mode. Since we are not using this object any more # this is not strictly necessary but is good style in case we expand # the test later on obj._in_construct_mode = False def test_external_file_with_correct_starting_frame(self): """Test that ValueError is not raised when the length of starting_frame is the same as the length of external_file.""" with warnings.catch_warnings(record=True) as w: ImageSeries( name="test_iS", external_file=["external_file", "external_file2", "external_file3"], format="external", unit="n.a.", starting_frame=[0, 15, 30], rate=0.2, ) self.assertEqual(w, []) def test_external_file_with_default_starting_frame(self): """Test that starting_frame is set to [0] if not provided, when external_file is has length 1.""" iS = ImageSeries( name="test_iS", external_file=["external_file"], format="external", unit="n.a.", starting_frame=None, rate=0.2, ) self.assertEqual(iS.starting_frame, [0]) def test_external_file_with_incorrect_format(self): """Test that ValueError is raised when external_file is provided but the format is not 'external'.""" msg = ( "ImageSeries 'test_iS': Format must be 'external' when external_file is specified." ) with self.assertRaisesWith(ValueError, msg): ImageSeries( name="test_iS", external_file=["external_file"], format="raw", unit="n.a.", starting_frame=[0], rate=0.2, ) def test_external_file_with_incorrect_format_construct_mode(self): """Test that UserWarning is raised when external_file is provided but the format is not 'external' while being in construct mode (i.e,. on data read).""" obj = ImageSeries.__new__(ImageSeries, container_source=None, parent=None, object_id="test", in_construct_mode=True) msg = ( "ImageSeries 'test_iS': Format must be 'external' when external_file is specified." ) with self.assertWarnsWith(warn_type=UserWarning, exc_msg=msg): obj.__init__( name="test_iS", external_file=["external_file"], format="raw", unit="n.a.", starting_frame=[0], rate=0.2, ) def test_external_file_default_format(self): """Test that format is set to 'external' if not provided, when external_file is provided.""" msg = ( "ImageSeries 'test_iS': The value for 'format' has been changed to 'external'. " "Setting a default value for 'format' is deprecated and will be changed to " "raising a ValueError in the next major release." ) with self.assertWarnsWith(DeprecationWarning, msg): iS = ImageSeries( name="test_iS", external_file=["external_file", "external_file2"], unit="n.a.", starting_frame=[0, 10], rate=0.2, ) self.assertEqual(iS.format, "external") def test_external_file_with_correct_format(self): """Test that warning is not raised when external_file is provided and format is external.""" with warnings.catch_warnings(record=True) as w: ImageSeries( name="test_iS", external_file=["external_file"], format="external", unit="n.a.", starting_frame=[0], rate=0.2, ) self.assertEqual(w, []) def test_external_file_with_data(self): """Test that ValueError is raised when external_file is provided and data is not None.""" msg = ( "ImageSeries 'test_iS': Either external_file or data must be specified (not None), but not both." ) with self.assertRaisesWith(ValueError, msg): ImageSeries( name="test_iS", external_file=["external_file"], data=np.ones((3, 3, 3)), format="external", unit="n.a.", starting_frame=[0], rate=0.2, ) def test_external_file_with_data_construct_mode(self): """Test that UserWarning is raised when external_file is provided and data is not None while being in construct mode (i.e,. on read).""" obj = ImageSeries.__new__(ImageSeries, container_source=None, parent=None, object_id="test", in_construct_mode=True) msg = ( "ImageSeries 'test_iS': Either external_file or data must be specified (not None), but not both." ) with self.assertWarnsWith(warn_type=UserWarning, exc_msg=msg): obj.__init__( name="test_iS", external_file=["external_file"], data=np.ones((3, 3, 3)), format="external", unit="n.a.", starting_frame=[0], rate=0.2, ) class IndexSeriesConstructor(TestCase): def test_init(self): image1 = Image(name='test_image', data=np.ones((10, 10))) image2 = Image(name='test_image2', data=np.ones((10, 10))) image_references = ImageReferences(name='order_of_images', data=[image2, image1]) images = Images(name='images_name', images=[image1, image2], order_of_images=image_references) iS = IndexSeries( name='test_iS', data=[1, 2, 3], unit='N/A', indexed_images=images, timestamps=[0.1, 0.2, 0.3] ) self.assertEqual(iS.name, 'test_iS') self.assertEqual(iS.unit, 'N/A') self.assertIs(iS.indexed_images, images) def test_init_bad_unit(self): ts = TimeSeries( name='test_ts', data=[1, 2, 3], unit='unit', timestamps=[0.1, 0.2, 0.3] ) msg = ("The 'unit' field of IndexSeries is fixed to the value 'N/A' starting in NWB 2.5. Passing " "a different value for 'unit' will raise an error in PyNWB 3.0.") with self.assertWarnsWith(PendingDeprecationWarning, msg): iS = IndexSeries( name='test_iS', data=[1, 2, 3], unit='na', indexed_timeseries=ts, timestamps=[0.1, 0.2, 0.3] ) self.assertEqual(iS.unit, 'N/A') def test_init_indexed_ts(self): ts = TimeSeries( name='test_ts', data=[1, 2, 3], unit='unit', timestamps=[0.1, 0.2, 0.3] ) msg = ("The indexed_timeseries field of IndexSeries is discouraged and will be deprecated in " "a future version of NWB. Use the indexed_images field instead.") with self.assertWarnsWith(PendingDeprecationWarning, msg): iS = IndexSeries( name='test_iS', data=[1, 2, 3], unit='N/A', indexed_timeseries=ts, timestamps=[0.1, 0.2, 0.3] ) self.assertIs(iS.indexed_timeseries, ts) class ImageMaskSeriesConstructor(TestCase): def test_init(self): iS = ImageSeries(name='test_iS', unit='unit', external_file=['external_file'], starting_frame=[0], format='external', timestamps=[1., .2]) ims = ImageMaskSeries(name='test_ims', unit='unit', masked_imageseries=iS, external_file=['external_file'], starting_frame=[0], format='external', timestamps=[1., 2.]) self.assertEqual(ims.name, 'test_ims') self.assertEqual(ims.unit, 'unit') self.assertIs(ims.masked_imageseries, iS) self.assertEqual(ims.external_file, ['external_file']) self.assertEqual(ims.starting_frame, [0]) self.assertEqual(ims.format, 'external') class OpticalSeriesConstructor(TestCase): def test_init(self): ts = OpticalSeries(name='test_ts', unit='unit', distance=1.0, field_of_view=[4, 5], orientation='orientation', external_file=['external_file'], starting_frame=[0], format='external', timestamps=[1., 2.]) self.assertEqual(ts.name, 'test_ts') self.assertEqual(ts.unit, 'unit') self.assertEqual(ts.distance, 1.0) self.assertEqual(ts.field_of_view, [4, 5]) self.assertEqual(ts.orientation, 'orientation') self.assertEqual(ts.external_file, ['external_file']) self.assertEqual(ts.starting_frame, [0]) self.assertEqual(ts.format, 'external') class TestImageSubtypes(TestCase): def test_grayscale_image(self): GrayscaleImage(name='test_grayscale_image', data=np.ones((2, 2))) def test_rgb_image(self): RGBImage(name='test_rgb_image', data=np.ones((2, 2, 3))) def test_rgba_image(self): RGBAImage('test_rgba_image', np.ones((2, 2, 4))) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_misc.py0000644000175100001730000002553414467767506017002 0ustar00runnerdockerimport numpy as np from hdmf.common import DynamicTable, VectorData, DynamicTableRegion from pynwb.misc import AnnotationSeries, AbstractFeatureSeries, IntervalSeries, Units, DecompositionSeries from pynwb.file import TimeSeries, ElectrodeTable as get_electrode_table from pynwb.device import Device from pynwb.ecephys import ElectrodeGroup from pynwb.testing import TestCase class AnnotationSeriesConstructor(TestCase): def test_init(self): aS = AnnotationSeries('test_aS', data=[1, 2, 3], timestamps=[1., 2., 3.]) self.assertEqual(aS.name, 'test_aS') aS.add_annotation(2.0, 'comment') class AbstractFeatureSeriesConstructor(TestCase): def test_init(self): aFS = AbstractFeatureSeries('test_aFS', ['feature units'], ['features'], timestamps=list()) self.assertEqual(aFS.name, 'test_aFS') self.assertEqual(aFS.feature_units, ['feature units']) self.assertEqual(aFS.features, ['features']) aFS.add_features(2.0, [1.]) class DecompositionSeriesConstructor(TestCase): def test_init(self): timeseries = TimeSeries(name='dummy timeseries', description='desc', data=np.ones((3, 3)), unit='Volts', timestamps=[1., 2., 3.]) bands = DynamicTable(name='bands', description='band info for LFPSpectralAnalysis', columns=[ VectorData(name='band_name', description='name of bands', data=['alpha', 'beta', 'gamma']), VectorData(name='band_limits', description='low and high cutoffs in Hz', data=np.ones((3, 2))) ]) spec_anal = DecompositionSeries(name='LFPSpectralAnalysis', description='my description', data=np.ones((3, 3, 3)), timestamps=[1., 2., 3.], source_timeseries=timeseries, metric='amplitude', bands=bands) self.assertEqual(spec_anal.name, 'LFPSpectralAnalysis') self.assertEqual(spec_anal.description, 'my description') np.testing.assert_equal(spec_anal.data, np.ones((3, 3, 3))) np.testing.assert_equal(spec_anal.timestamps, [1., 2., 3.]) self.assertEqual(spec_anal.bands['band_name'].data, ['alpha', 'beta', 'gamma']) np.testing.assert_equal(spec_anal.bands['band_limits'].data, np.ones((3, 2))) self.assertEqual(spec_anal.source_timeseries, timeseries) self.assertEqual(spec_anal.metric, 'amplitude') def test_init_delayed_bands(self): timeseries = TimeSeries(name='dummy timeseries', description='desc', data=np.ones((3, 3)), unit='Volts', timestamps=np.ones((3,))) spec_anal = DecompositionSeries(name='LFPSpectralAnalysis', description='my description', data=np.ones((3, 3, 3)), timestamps=[1., 2., 3.], source_timeseries=timeseries, metric='amplitude') for band_name in ['alpha', 'beta', 'gamma']: spec_anal.add_band(band_name=band_name, band_limits=(1., 1.), band_mean=1., band_stdev=1.) self.assertEqual(spec_anal.name, 'LFPSpectralAnalysis') self.assertEqual(spec_anal.description, 'my description') np.testing.assert_equal(spec_anal.data, np.ones((3, 3, 3))) np.testing.assert_equal(spec_anal.timestamps, [1., 2., 3.]) self.assertEqual(spec_anal.bands['band_name'].data, ['alpha', 'beta', 'gamma']) np.testing.assert_equal(spec_anal.bands['band_limits'].data, np.ones((3, 2))) self.assertEqual(spec_anal.source_timeseries, timeseries) self.assertEqual(spec_anal.metric, 'amplitude') @staticmethod def make_electrode_table(self): """ Make an electrode table, electrode group, and device """ self.table = get_electrode_table() self.dev1 = Device(name='dev1') self.group = ElectrodeGroup(name='tetrode1', description='tetrode description', location='tetrode location', device=self.dev1) for i in range(4): self.table.add_row(location='CA1', group=self.group, group_name='tetrode1') def test_init_with_source_channels(self): self.make_electrode_table(self) region = DynamicTableRegion(name='source_channels', data=[0, 2], description='the first and third electrodes', table=self.table) data = np.random.randn(100, 2, 30) timestamps = np.arange(100)/100 ds = DecompositionSeries(name='test_DS', data=data, source_channels=region, timestamps=timestamps, metric='amplitude') self.assertIs(ds.source_channels, region) class IntervalSeriesConstructor(TestCase): def test_init(self): data = [1.0, -1.0, 1.0, -1.0] timestamps = [0.0, 1.0, 2.0, 3.0] iS = IntervalSeries('test_iS', data=data, timestamps=timestamps) self.assertEqual(iS.name, 'test_iS') self.assertEqual(iS.data, data) self.assertEqual(iS.timestamps, timestamps) def test_add_interval(self): data = [1.0, -1.0, 1.0, -1.0] timestamps = [0.0, 1.0, 2.0, 3.0] iS = IntervalSeries('test_iS', data=data, timestamps=timestamps) iS.add_interval(4.0, 5.0) data.append(1.0) data.append(-1.0) timestamps.append(4.0) timestamps.append(5.0) self.assertEqual(iS.data, data) self.assertEqual(iS.timestamps, timestamps) class UnitsTests(TestCase): def test_init(self): ut = Units() self.assertEqual(ut.name, 'Units') self.assertFalse(ut.columns) def test_add_spike_times(self): ut = Units() ut.add_unit(spike_times=[0, 1, 2]) ut.add_unit(spike_times=[3, 4, 5]) self.assertEqual(ut.id.data, [0, 1]) self.assertEqual(ut['spike_times'].target.data, [0, 1, 2, 3, 4, 5]) self.assertEqual(ut['spike_times'].data, [3, 6]) self.assertEqual(ut['spike_times'][0], [0, 1, 2]) self.assertEqual(ut['spike_times'][1], [3, 4, 5]) def test_add_waveforms(self): ut = Units() wf1 = [ [ # elec 1 [1, 2, 3], [1, 2, 3], [1, 2, 3] ], [ # elec 2 [1, 2, 3], [1, 2, 3], [1, 2, 3] ] ] wf2 = [ [ # elec 1 [1, 2, 3], # spike 1, [sample 1, sample 2, sample 3] [1, 2, 3], # spike 2 [1, 2, 3], # spike 3 [1, 2, 3] # spike 4 ], [ # elec 2 [1, 2, 3], # spike 1 [1, 2, 3], # spike 2 [1, 2, 3], # spike 3 [1, 2, 3] # spike 4 ], [ # elec 3 [1, 2, 3], # spike 1 [1, 2, 3], # spike 2 [1, 2, 3], # spike 3 [1, 2, 3] # spike 4 ] ] ut.add_unit(waveforms=wf1) ut.add_unit(waveforms=wf2) self.assertEqual(ut.id.data, [0, 1]) self.assertEqual(ut['waveforms'].target.data, [3, 6, 10, 14, 18]) self.assertEqual(ut['waveforms'].data, [2, 5]) self.assertListEqual(ut['waveforms'][0], wf1) self.assertListEqual(ut['waveforms'][1], wf2) def test_get_spike_times(self): ut = Units() ut.add_unit(spike_times=[0, 1, 2]) ut.add_unit(spike_times=[3, 4, 5]) self.assertTrue(all(ut.get_unit_spike_times(0) == np.array([0, 1, 2]))) self.assertTrue(all(ut.get_unit_spike_times(1) == np.array([3, 4, 5]))) @staticmethod def test_get_spike_times_interval(): ut = Units() ut.add_unit(spike_times=[0, 1, 2]) ut.add_unit(spike_times=[3, 4, 5]) np.testing.assert_array_equal(ut.get_unit_spike_times(0, (.5, 3)), [1, 2]) np.testing.assert_array_equal(ut.get_unit_spike_times(0, (-.5, 1.1)), [0, 1]) def test_get_spike_times_multi(self): ut = Units() ut.add_unit(spike_times=[0, 1, 2]) ut.add_unit(spike_times=[3, 4, 5]) np.testing.assert_array_equal(ut.get_unit_spike_times((0, 1)), [[0, 1, 2], [3, 4, 5]]) def test_get_spike_times_multi_interval(self): ut = Units() ut.add_unit(spike_times=[0, 1, 2]) ut.add_unit(spike_times=[3, 4, 5]) np.testing.assert_array_equal(ut.get_unit_spike_times((0, 1), (1.5, 3.5)), [[2], [3]]) def test_times(self): ut = Units() ut.add_unit(spike_times=[0, 1, 2]) ut.add_unit(spike_times=[3, 4, 5]) self.assertTrue(all(ut['spike_times'][0] == np.array([0, 1, 2]))) self.assertTrue(all(ut['spike_times'][1] == np.array([3, 4, 5]))) def test_get_obs_intervals(self): ut = Units() ut.add_unit(obs_intervals=[[0, 1]]) ut.add_unit(obs_intervals=[[2, 3], [4, 5]]) self.assertTrue(np.all(ut.get_unit_obs_intervals(0) == np.array([[0, 1]]))) self.assertTrue(np.all(ut.get_unit_obs_intervals(1) == np.array([[2, 3], [4, 5]]))) def test_obs_intervals(self): ut = Units() ut.add_unit(obs_intervals=[[0, 1]]) ut.add_unit(obs_intervals=[[2, 3], [4, 5]]) self.assertTrue(np.all(ut['obs_intervals'][0] == np.array([[0, 1]]))) self.assertTrue(np.all(ut['obs_intervals'][1] == np.array([[2, 3], [4, 5]]))) def test_times_and_intervals(self): ut = Units() ut.add_unit(spike_times=[0, 1, 2], obs_intervals=[[0, 2]]) ut.add_unit(spike_times=[3, 4, 5], obs_intervals=[[2, 3], [4, 5]]) self.assertTrue(all(ut['spike_times'][0] == np.array([0, 1, 2]))) self.assertTrue(all(ut['spike_times'][1] == np.array([3, 4, 5]))) self.assertTrue(np.all(ut['obs_intervals'][0] == np.array([[0, 2]]))) self.assertTrue(np.all(ut['obs_intervals'][1] == np.array([[2, 3], [4, 5]]))) def test_electrode_group(self): ut = Units() device = Device('test_device') electrode_group = ElectrodeGroup('test_electrode_group', 'description', 'location', device) ut.add_unit(electrode_group=electrode_group) self.assertEqual(ut['electrode_group'][0], electrode_group) def test_waveform_attrs(self): ut = Units(waveform_rate=40000.) self.assertEqual(ut.waveform_rate, 40000.) self.assertEqual(ut.waveform_unit, 'volts') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_mock.py0000644000175100001730000000523014467767506016767 0ustar00runnerdockerfrom pynwb import NWBHDF5IO from pynwb.testing.mock.file import mock_Subject, mock_NWBFile from pynwb.testing.mock.base import mock_TimeSeries from pynwb.testing.mock.ophys import ( mock_ImagingPlane, mock_OnePhotonSeries, mock_TwoPhotonSeries, mock_RoiResponseSeries, mock_PlaneSegmentation, mock_OpticalChannel, mock_Fluorescence, mock_DfOverF, mock_ImageSegmentation, ) from pynwb.testing.mock.ogen import ( mock_OptogeneticStimulusSite, mock_OptogeneticSeries ) from pynwb.testing.mock.device import mock_Device from pynwb.testing.mock.behavior import ( mock_Position, mock_PupilTracking, mock_CompassDirection, mock_SpatialSeries, ) from pynwb.testing.mock.ecephys import ( mock_ElectrodeGroup, mock_ElectrodeTable, mock_ElectricalSeries, mock_SpikeEventSeries, ) from pynwb.testing.mock.icephys import ( mock_IntracellularElectrode, mock_CurrentClampSeries, mock_IZeroClampSeries, mock_VoltageClampSeries, mock_VoltageClampStimulusSeries, mock_CurrentClampStimulusSeries, mock_IntracellularRecordingsTable, ) import pytest from pynwb.testing.mock.utils import name_generator, name_generator_registry mock_functions = [ mock_ImagingPlane, mock_OnePhotonSeries, mock_TwoPhotonSeries, mock_RoiResponseSeries, mock_PlaneSegmentation, mock_OpticalChannel, mock_Fluorescence, mock_DfOverF, mock_ImageSegmentation, mock_OptogeneticStimulusSite, mock_OptogeneticSeries, mock_Device, mock_Position, mock_PupilTracking, mock_CompassDirection, mock_SpatialSeries, mock_ElectrodeGroup, mock_ElectrodeTable, mock_ElectricalSeries, mock_SpikeEventSeries, mock_Subject, mock_NWBFile, mock_TimeSeries, mock_CurrentClampSeries, mock_IZeroClampSeries, mock_VoltageClampSeries, mock_VoltageClampStimulusSeries, mock_IntracellularElectrode, mock_CurrentClampStimulusSeries, mock_IntracellularRecordingsTable, ] @pytest.mark.parametrize("mock_function", mock_functions) def test_mock(mock_function): mock_function() @pytest.mark.parametrize("mock_function", mock_functions) def test_mock_write(mock_function, tmp_path): if mock_function is mock_NWBFile: return nwbfile = mock_NWBFile() assert mock_function(nwbfile=nwbfile) is not None test_file = tmp_path / (mock_function.__name__ + ".nwb") with NWBHDF5IO(test_file, "w") as io: io.write(nwbfile) def test_name_generator(): name_generator_registry.clear() # reset registry assert name_generator("TimeSeries") == "TimeSeries" assert name_generator("TimeSeries") == "TimeSeries2" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_ogen.py0000644000175100001730000000172314467767506016771 0ustar00runnerdockerfrom pynwb.ogen import OptogeneticSeries, OptogeneticStimulusSite from pynwb.ecephys import Device from pynwb.testing import TestCase class OptogeneticSeriesConstructor(TestCase): def test_init(self): device = Device('name') oS = OptogeneticStimulusSite( name='site1', device=device, description='description', excitation_lambda=300., location='location' ) self.assertEqual(oS.name, 'site1') self.assertEqual(oS.device, device) self.assertEqual(oS.description, 'description') self.assertEqual(oS.excitation_lambda, 300.) self.assertEqual(oS.location, 'location') iS = OptogeneticSeries( name='test_iS', data=[1, 2, 3], site=oS, timestamps=[0.1, 0.2, 0.3] ) self.assertEqual(iS.name, 'test_iS') self.assertEqual(iS.unit, 'watts') self.assertEqual(iS.site, oS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_ophys.py0000644000175100001730000004546014467767506017211 0ustar00runnerdockerimport warnings import numpy as np from pynwb.base import TimeSeries from pynwb.device import Device from pynwb.image import ImageSeries from pynwb.ophys import ( OnePhotonSeries, TwoPhotonSeries, RoiResponseSeries, DfOverF, Fluorescence, PlaneSegmentation, ImageSegmentation, OpticalChannel, ImagingPlane, MotionCorrection, CorrectedImageStack ) from pynwb.testing import TestCase def create_imaging_plane(): oc = OpticalChannel( name='test_optical_channel', description='description', emission_lambda=500. ) device = Device(name='device_name') ip = ImagingPlane( name='test_imaging_plane', optical_channel=oc, description='description', device=device, excitation_lambda=600., imaging_rate=300., indicator='indicator', location='location', reference_frame='reference_frame', origin_coords=[10, 20], origin_coords_unit='oc_unit', grid_spacing=[1, 2, 3], grid_spacing_unit='gs_unit' ) return ip def create_plane_segmentation(): w, h = 5, 5 img_mask = [[[1.0 for x in range(w)] for y in range(h)], [[2.0 for x in range(w)] for y in range(h)]] pix_mask = [[1, 2, 1.0], [3, 4, 1.0], [5, 6, 1.0], [7, 8, 2.0], [9, 10, 2.0]] iSS = ImageSeries( name='test_iS', unit='unit', external_file=['external_file'], starting_frame=[0], format='external', timestamps=[1., 2.] ) ip = create_imaging_plane() pS = PlaneSegmentation( description='description', imaging_plane=ip, name='test_name', reference_images=iSS ) pS.add_roi(pixel_mask=pix_mask[0:3], image_mask=img_mask[0]) pS.add_roi(pixel_mask=pix_mask[3:5], image_mask=img_mask[1]) return pS class OpticalChannelConstructor(TestCase): def test_init(self): oc = OpticalChannel( name='test_optical_channel', description='description', emission_lambda=500. ) self.assertEqual(oc.name, 'test_optical_channel') self.assertEqual(oc.description, 'description') self.assertEqual(oc.emission_lambda, 500.) class ImagingPlaneConstructor(TestCase): def set_up_dependencies(self): oc = OpticalChannel( name='test_optical_channel', description='description', emission_lambda=500. ) device = Device(name='device_name') return oc, device def test_init(self): oc, device = self.set_up_dependencies() ip = ImagingPlane( name='test_imaging_plane', optical_channel=oc, description='description', device=device, excitation_lambda=600., imaging_rate=300., indicator='indicator', location='location', reference_frame='reference_frame', origin_coords=[10, 20], origin_coords_unit='oc_unit', grid_spacing=[1, 2, 3], grid_spacing_unit='gs_unit' ) self.assertEqual(ip.optical_channel[0], oc) self.assertEqual(ip.device, device) self.assertEqual(ip.excitation_lambda, 600.) self.assertEqual(ip.imaging_rate, 300.) self.assertEqual(ip.indicator, 'indicator') self.assertEqual(ip.location, 'location') self.assertEqual(ip.reference_frame, 'reference_frame') self.assertEqual(ip.origin_coords, [10, 20]) self.assertEqual(ip.origin_coords_unit, 'oc_unit') self.assertEqual(ip.grid_spacing, [1, 2, 3]) self.assertEqual(ip.grid_spacing_unit, 'gs_unit') def test_manifold_deprecated(self): oc, device = self.set_up_dependencies() msg = "The 'manifold' argument is deprecated in favor of 'origin_coords' and 'grid_spacing'." with self.assertWarnsWith(DeprecationWarning, msg): ImagingPlane( name='test_imaging_plane', optical_channel=oc, description='description', device=device, excitation_lambda=600., imaging_rate=300., indicator='indicator', location='location', manifold=(1, 1, (2, 2, 2)) ) def test_conversion_deprecated(self): oc, device = self.set_up_dependencies() msg = "The 'conversion' argument is deprecated in favor of 'origin_coords' and 'grid_spacing'." with self.assertWarnsWith(DeprecationWarning, msg): ImagingPlane( name='test_imaging_plane', optical_channel=oc, description='description', device=device, excitation_lambda=600., imaging_rate=300., indicator='indicator', location='location', conversion=2.0 ) def test_unit_deprecated(self): oc, device = self.set_up_dependencies() msg = "The 'unit' argument is deprecated in favor of 'origin_coords_unit' and 'grid_spacing_unit'." with self.assertWarnsWith(DeprecationWarning, msg): ImagingPlane( name='test_imaging_plane', optical_channel=oc, description='description', device=device, excitation_lambda=600., imaging_rate=300., indicator='indicator', location='location', reference_frame='reference_frame', unit='my_unit' ) class OnePhotonSeriesConstructor(TestCase): def test_init(self): ip = create_imaging_plane() one_photon_series = OnePhotonSeries( name="test_one_photon_series", unit="unit", imaging_plane=ip, pmt_gain=1., scan_line_rate=2., exposure_time=123., binning=2, power=9001., intensity=5., external_file=["external_file"], starting_frame=[0], format="external", timestamps=list(), ) self.assertEqual(one_photon_series.name, 'test_one_photon_series') self.assertEqual(one_photon_series.unit, 'unit') self.assertEqual(one_photon_series.imaging_plane, ip) self.assertEqual(one_photon_series.pmt_gain, 1.) self.assertEqual(one_photon_series.scan_line_rate, 2.) self.assertEqual(one_photon_series.exposure_time, 123.) self.assertEqual(one_photon_series.binning, 2) self.assertEqual(one_photon_series.power, 9001.) self.assertEqual(one_photon_series.intensity, 5.) self.assertEqual(one_photon_series.external_file, ["external_file"]) self.assertEqual(one_photon_series.starting_frame, [0]) self.assertEqual(one_photon_series.format, "external") self.assertIsNone(one_photon_series.dimension) def test_negative_binning_assertion(self): ip = create_imaging_plane() with self.assertRaisesWith(exc_type=ValueError, exc_msg="Binning value must be >= 0: -1"): OnePhotonSeries( name="test_one_photon_series_binning_assertion", unit="unit", data=np.empty(shape=(10, 100, 100)), imaging_plane=ip, rate=1., binning=-1, ) class TwoPhotonSeriesConstructor(TestCase): def test_init(self): ip = create_imaging_plane() tPS = TwoPhotonSeries( name='test_tPS', unit='unit', field_of_view=[2., 3.], imaging_plane=ip, pmt_gain=1.0, scan_line_rate=2.0, external_file=['external_file'], starting_frame=[0], format='external', timestamps=list() ) self.assertEqual(tPS.name, 'test_tPS') self.assertEqual(tPS.unit, 'unit') self.assertEqual(tPS.field_of_view, [2., 3.]) self.assertEqual(tPS.imaging_plane, ip) self.assertEqual(tPS.pmt_gain, 1.0) self.assertEqual(tPS.scan_line_rate, 2.0) self.assertEqual(tPS.external_file, ['external_file']) self.assertEqual(tPS.starting_frame, [0]) self.assertEqual(tPS.format, 'external') self.assertIsNone(tPS.dimension) class MotionCorrectionConstructor(TestCase): def test_init(self): corrected = ImageSeries( name='corrected', data=np.ones((1000, 100, 100)), unit='na', format='raw', starting_time=0.0, rate=1.0 ) xy_translation = TimeSeries( name='xy_translation', data=np.ones((1000, 2)), unit='pixels', starting_time=0.0, rate=1.0, ) ip = create_imaging_plane() image_series = TwoPhotonSeries( name='TwoPhotonSeries1', data=np.ones((1000, 100, 100)), imaging_plane=ip, rate=1.0, unit='normalized amplitude' ) corrected_image_stack = CorrectedImageStack( corrected=corrected, original=image_series, xy_translation=xy_translation, ) motion_correction = MotionCorrection(corrected_image_stacks=[corrected_image_stack]) self.assertEqual(motion_correction.corrected_image_stacks['CorrectedImageStack'], corrected_image_stack) class CorrectedImageStackConstructor(TestCase): def test_init(self): is1 = ImageSeries( name='corrected', unit='unit', external_file=['external_file'], starting_frame=[0], format='external', timestamps=[1., 2.] ) is2 = ImageSeries( name='is2', unit='unit', external_file=['external_file'], starting_frame=[0], format='external', timestamps=[1., 2.] ) tstamps = np.arange(1.0, 100.0, 0.1, dtype=np.float64) ts = TimeSeries( name='xy_translation', data=list(range(len(tstamps))), unit='unit', timestamps=tstamps ) cis = CorrectedImageStack( corrected=is1, original=is2, xy_translation=ts ) self.assertEqual(cis.corrected, is1) self.assertEqual(cis.original, is2) self.assertEqual(cis.xy_translation, ts) class RoiResponseSeriesConstructor(TestCase): def test_init(self): ps = create_plane_segmentation() rt_region = ps.create_roi_table_region(description='the second ROI', region=[0]) ts = RoiResponseSeries( name='test_ts', data=[1, 2, 3], rois=rt_region, unit='unit', timestamps=[0.1, 0.2, 0.3] ) self.assertEqual(ts.name, 'test_ts') self.assertEqual(ts.unit, 'unit') self.assertEqual(ts.rois, rt_region) def test_warnings(self): ps = create_plane_segmentation() rt_region = ps.create_roi_table_region(description='the first two ROIs', region=[0, 1]) with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") RoiResponseSeries( name="test_ts1", data=np.ones((6, 2)), rois=rt_region, rate=30000., unit="n.a.", ) self.assertEqual(w, []) with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") RoiResponseSeries( name="test_ts1", data=np.ones((6, 3)), rois=rt_region, unit="n.a.", timestamps=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5] ) self.assertEqual(len(w), 1) assert ( "RoiResponseSeries 'test_ts1': The second dimension of data does not match the length of rois. " "Your data may be transposed." ) in str(w[-1].message) with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") RoiResponseSeries( name="test_ts1", data=np.ones((2, 6)), rois=rt_region, rate=30000., unit="n.a.", ) self.assertEqual(len(w), 1) assert ( "RoiResponseSeries 'test_ts1': The second dimension of data does not match the length of rois, " "but instead the first does. Data is oriented incorrectly and should be transposed." ) in str(w[-1].message) class DfOverFConstructor(TestCase): def test_init(self): ps = create_plane_segmentation() rt_region = ps.create_roi_table_region(description='the second ROI', region=[1]) rrs = RoiResponseSeries( name='test_ts', data=[1, 2, 3], rois=rt_region, unit='unit', timestamps=[0.1, 0.2, 0.3] ) dof = DfOverF(rrs) self.assertEqual(dof.roi_response_series['test_ts'], rrs) class FluorescenceConstructor(TestCase): def test_init(self): ps = create_plane_segmentation() rt_region = ps.create_roi_table_region(description='the second ROI', region=[1]) ts = RoiResponseSeries( name='test_ts', data=[1, 2, 3], rois=rt_region, unit='unit', timestamps=[0.1, 0.2, 0.3] ) ff = Fluorescence(ts) self.assertEqual(ff.roi_response_series['test_ts'], ts) class ImageSegmentationConstructor(TestCase): def test_init(self): ps = create_plane_segmentation() iS = ImageSegmentation(ps, name='test_iS') self.assertEqual(iS.name, 'test_iS') self.assertEqual(iS.plane_segmentations[ps.name], ps) self.assertEqual(iS[ps.name], iS.plane_segmentations[ps.name]) class PlaneSegmentationConstructor(TestCase): def set_up_dependencies(self): iSS = ImageSeries( name='test_iS', unit='unit', external_file=['external_file'], starting_frame=[0], format='external', timestamps=[1., 2.] ) ip = create_imaging_plane() return iSS, ip def create_basic_plane_segmentation(self): """Creates a basic plane segmentation used for testing""" iSS, ip = self.set_up_dependencies() pS = PlaneSegmentation( description='description', imaging_plane=ip, name='test_name', reference_images=iSS ) return iSS, ip, pS def test_init(self): w, h = 5, 5 img_mask = [[[1.0 for x in range(w)] for y in range(h)], [[2.0 for x in range(w)] for y in range(h)]] pix_mask = [[1, 2, 1.0], [3, 4, 1.0], [5, 6, 1.0], [7, 8, 2.0], [9, 10, 2.0]] iSS, ip, pS = self.create_basic_plane_segmentation() pS.add_roi(pixel_mask=pix_mask[0:3], image_mask=img_mask[0]) pS.add_roi(pixel_mask=pix_mask[3:5], image_mask=img_mask[1]) self.assertEqual(pS.name, 'test_name') self.assertEqual(pS.description, 'description') self.assertEqual(pS.imaging_plane, ip) self.assertEqual(pS.reference_images, (iSS,)) self.assertEqual(pS['pixel_mask'].target.data, pix_mask) self.assertEqual(pS['pixel_mask'][0], pix_mask[0:3]) self.assertEqual(pS['pixel_mask'][1], pix_mask[3:5]) self.assertEqual(pS['image_mask'].data, img_mask) def test_init_pixel_mask(self): pix_mask = [[1, 2, 1.0], [3, 4, 1.0], [5, 6, 1.0], [7, 8, 2.0], [9, 10, 2.0]] iSS, ip, pS = self.create_basic_plane_segmentation() pS.add_roi(pixel_mask=pix_mask[0:3]) pS.add_roi(pixel_mask=pix_mask[3:5]) self.assertEqual(pS.name, 'test_name') self.assertEqual(pS.description, 'description') self.assertEqual(pS.imaging_plane, ip) self.assertEqual(pS.reference_images, (iSS,)) self.assertEqual(pS['pixel_mask'].target.data, pix_mask) self.assertEqual(pS['pixel_mask'][0], pix_mask[0:3]) self.assertEqual(pS['pixel_mask'][1], pix_mask[3:5]) def test_init_voxel_mask(self): vox_mask = [[1, 2, 3, 1.0], [3, 4, 1, 1.0], [5, 6, 3, 1.0], [7, 8, 3, 2.0], [9, 10, 2, 2.0]] iSS, ip, pS = self.create_basic_plane_segmentation() pS.add_roi(voxel_mask=vox_mask[0:3]) pS.add_roi(voxel_mask=vox_mask[3:5]) self.assertEqual(pS.name, 'test_name') self.assertEqual(pS.description, 'description') self.assertEqual(pS.imaging_plane, ip) self.assertEqual(pS.reference_images, (iSS,)) self.assertEqual(pS['voxel_mask'].target.data, vox_mask) self.assertEqual(pS['voxel_mask'][0], vox_mask[0:3]) self.assertEqual(pS['voxel_mask'][1], vox_mask[3:5]) def test_init_image_mask(self): w, h = 5, 5 img_mask = [[[1.0 for x in range(w)] for y in range(h)], [[2.0 for x in range(w)] for y in range(h)]] iSS, ip, pS = self.create_basic_plane_segmentation() pS.add_roi(image_mask=img_mask[0]) pS.add_roi(image_mask=img_mask[1]) self.assertEqual(pS.name, 'test_name') self.assertEqual(pS.description, 'description') self.assertEqual(pS.imaging_plane, ip) self.assertEqual(pS.reference_images, (iSS,)) self.assertEqual(pS['image_mask'].data, img_mask) def test_init_3d_image_mask(self): img_masks = np.random.randn(2, 20, 30, 4) _, _, pS = self.create_basic_plane_segmentation() pS.add_roi(image_mask=img_masks[0]) pS.add_roi(image_mask=img_masks[1]) self.assertTrue(np.allclose(pS['image_mask'][0], img_masks[0])) self.assertTrue(np.allclose(pS['image_mask'][1], img_masks[1])) def test_conversion_of_2d_pixel_mask_to_image_mask(self): pixel_mask = [[0, 0, 1.0], [1, 0, 2.0], [2, 0, 2.0]] _, _, pS = self.create_basic_plane_segmentation() img_mask = pS.pixel_to_image(pixel_mask) np.testing.assert_allclose(img_mask, np.asarray([[1, 2, 2.0], [0, 0, 0.0], [0, 0, 0.0]])) def test_conversion_of_2d_image_mask_to_pixel_mask(self): image_mask = np.asarray([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]) _, _, pS = self.create_basic_plane_segmentation() pixel_mask = pS.image_to_pixel(image_mask) np.testing.assert_allclose(pixel_mask, np.asarray([[0, 0, 1.0], [1, 1, 1.0], [2, 2, 1.0]])) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_resources.py0000644000175100001730000000036514467767506020054 0ustar00runnerdockerfrom pynwb.resources import HERD from pynwb.testing import TestCase class TestNWBContainer(TestCase): def test_constructor(self): """ Test constructor """ er = HERD() self.assertIsInstance(er, HERD) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_retinotopy.py0000644000175100001730000001753114467767506020261 0ustar00runnerdockerimport numpy as np from pynwb.retinotopy import ImagingRetinotopy, AxisMap, RetinotopyImage, FocalDepthImage, RetinotopyMap from pynwb.testing import TestCase class ImageRetinotopyConstructor(TestCase): def setUp(self): data = np.ones((2, 2)) field_of_view = [1, 2] dimension = [1, 2] self.sign_map = RetinotopyMap('sign_map', data, field_of_view, dimension) self.axis_1_phase_map = AxisMap('axis_1_phase_map', data, field_of_view, 'unit', dimension) self.axis_1_power_map = AxisMap('axis_1_power_map', data, field_of_view, 'unit', dimension) self.axis_2_phase_map = AxisMap('axis_2_phase_map', data, field_of_view, 'unit', dimension) self.axis_2_power_map = AxisMap('axis_2_power_map', data, field_of_view, 'unit', dimension) self.axis_descriptions = ['altitude', 'azimuth'] data = [[1, 1], [1, 1]] bits_per_pixel = 8 dimension = [3, 4] format = 'raw' field_of_view = [1, 2] focal_depth = 1.0 self.focal_depth_image = FocalDepthImage('focal_depth_image', data, bits_per_pixel, dimension, format, field_of_view, focal_depth) self.vasculature_image = RetinotopyImage('vasculature_image', np.uint16(data), bits_per_pixel, dimension, format, field_of_view) def test_init(self): """Test that ImagingRetinotopy constructor sets properties correctly.""" msg = ('The ImagingRetinotopy class currently cannot be written to or read from a file. This is a known bug ' 'and will be fixed in a future release of PyNWB.') with self.assertWarnsWith(UserWarning, msg): ir = ImagingRetinotopy(self.sign_map, self.axis_1_phase_map, self.axis_1_power_map, self.axis_2_phase_map, self.axis_2_power_map, self.axis_descriptions, self.focal_depth_image, self.vasculature_image) self.assertEqual(ir.sign_map, self.sign_map) self.assertEqual(ir.axis_1_phase_map, self.axis_1_phase_map) self.assertEqual(ir.axis_1_power_map, self.axis_1_power_map) self.assertEqual(ir.axis_2_phase_map, self.axis_2_phase_map) self.assertEqual(ir.axis_2_power_map, self.axis_2_power_map) self.assertEqual(ir.axis_descriptions, self.axis_descriptions) self.assertEqual(ir.focal_depth_image, self.focal_depth_image) self.assertEqual(ir.vasculature_image, self.vasculature_image) def test_init_axis_descriptions_wrong_shape(self): """Test that creating a ImagingRetinotopy with a axis descriptions argument that is not 2 elements raises an error. """ self.axis_descriptions = ['altitude', 'azimuth', 'extra'] msg = "ImagingRetinotopy.__init__: incorrect shape for 'axis_descriptions' (got '(3,)', expected '(2,)')" with self.assertRaisesWith(ValueError, msg): ImagingRetinotopy(self.sign_map, self.axis_1_phase_map, self.axis_1_power_map, self.axis_2_phase_map, self.axis_2_power_map, self.axis_descriptions, self.focal_depth_image, self.vasculature_image) class RetinotopyImageConstructor(TestCase): def test_init(self): """Test that RetinotopyImage constructor sets properties correctly.""" data = [[1, 1], [1, 1]] bits_per_pixel = 8 dimension = [3, 4] format = 'raw' field_of_view = [1, 2] image = RetinotopyImage('vasculature_image', data, bits_per_pixel, dimension, format, field_of_view) self.assertEqual(image.name, 'vasculature_image') self.assertEqual(image.data, data) self.assertEqual(image.bits_per_pixel, bits_per_pixel) self.assertEqual(image.dimension, dimension) self.assertEqual(image.format, format) self.assertEqual(image.field_of_view, field_of_view) def test_init_dimension_wrong_shape(self): """Test that creating a RetinotopyImage with a dimension argument that is not 2 elements raises an error.""" data = [[1, 1], [1, 1]] bits_per_pixel = 8 dimension = [3, 4, 5] format = 'raw' field_of_view = [1, 2] msg = "RetinotopyImage.__init__: incorrect shape for 'dimension' (got '(3,)', expected '(2,)')" with self.assertRaisesWith(ValueError, msg): RetinotopyImage('vasculature_image', data, bits_per_pixel, dimension, format, field_of_view) def test_init_fov_wrong_shape(self): """Test that creating a RetinotopyImage with a field of view argument that is not 2 elements raises an error.""" data = [[1, 1], [1, 1]] bits_per_pixel = 8 dimension = [3, 4] format = 'raw' field_of_view = [1, 2, 3] msg = "RetinotopyImage.__init__: incorrect shape for 'field_of_view' (got '(3,)', expected '(2,)')" with self.assertRaisesWith(ValueError, msg): RetinotopyImage('vasculature_image', data, bits_per_pixel, dimension, format, field_of_view) class RetinotopyMapConstructor(TestCase): def test_init(self): """Test that RetinotopyMap constructor sets properties correctly.""" data = np.ones((2, 2)) field_of_view = [1, 2] dimension = [1, 2] map = RetinotopyMap('sign_map', data, field_of_view, dimension) self.assertEqual(map.name, 'sign_map') np.testing.assert_array_equal(map.data, data) self.assertEqual(map.field_of_view, field_of_view) self.assertEqual(map.dimension, dimension) class AxisMapConstructor(TestCase): def test_init(self): """Test that AxisMap constructor sets properties correctly.""" data = np.ones((2, 2)) field_of_view = [1, 2] dimension = [1, 2] map = AxisMap('axis_1_phase', data, field_of_view, 'unit', dimension) self.assertEqual(map.name, 'axis_1_phase') np.testing.assert_array_equal(map.data, data) self.assertEqual(map.field_of_view, field_of_view) self.assertEqual(map.dimension, dimension) self.assertEqual(map.unit, 'unit') def test_init_dimension_wrong_shape(self): """Test that creating an AxisMap with a dimension argument that is not 2 elements raises an error.""" data = np.ones((2, 2)) field_of_view = [1, 2] dimension = [1, 2, 3] msg = "AxisMap.__init__: incorrect shape for 'dimension' (got '(3,)', expected '(2,)')" with self.assertRaisesWith(ValueError, msg): AxisMap('axis_1_phase', data, field_of_view, 'unit', dimension) def test_init_fov_wrong_shape(self): """Test that creating an AxisMap with a dimension argument that is not 2 elements raises an error.""" data = np.ones((2, 2)) field_of_view = [1, 2, 3] dimension = [1, 2] msg = "AxisMap.__init__: incorrect shape for 'field_of_view' (got '(3,)', expected '(2,)')" with self.assertRaisesWith(ValueError, msg): AxisMap('axis_1_phase', data, field_of_view, 'unit', dimension) class FocalDepthImageConstructor(TestCase): def test_init(self): """Test that FocalDepthImage constructor sets properties correctly.""" data = [[1, 1], [1, 1]] bits_per_pixel = 8 dimension = [3, 4] format = 'raw' field_of_view = [1, 2] focal_depth = 1.0 image = FocalDepthImage('focal_depth_image', data, bits_per_pixel, dimension, format, field_of_view, focal_depth) self.assertEqual(image.name, 'focal_depth_image') self.assertEqual(image.data, data) self.assertEqual(image.bits_per_pixel, bits_per_pixel) self.assertEqual(image.dimension, dimension) self.assertEqual(image.format, format) self.assertEqual(image.field_of_view, field_of_view) self.assertEqual(image.focal_depth, focal_depth) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_scratch.py0000644000175100001730000001377514467767506017502 0ustar00runnerdockerfrom datetime import datetime from dateutil.tz import tzlocal import numpy as np from numpy.testing import assert_array_equal import pandas as pd from pynwb import NWBFile, TimeSeries from pynwb.core import ScratchData, DynamicTable from pynwb.testing import TestCase class TestScratchData(TestCase): def setUp(self): self.nwbfile = NWBFile( session_description='a file to test writing and reading scratch data', identifier='TEST_scratch', session_start_time=datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal()) ) def test_constructor_list(self): sd = ScratchData( name='foo', data=[1, 2, 3, 4], description='test scratch', ) self.assertEqual(sd.name, 'foo') self.assertListEqual(sd.data, [1, 2, 3, 4]) self.assertEqual(sd.description, 'test scratch') def test_add_scratch_int(self): ret = self.nwbfile.add_scratch(2, name='test', description='test data') self.assertIsInstance(ret, ScratchData) self.assertEqual(ret.name, 'test') self.assertEqual(ret.data, 2) self.assertEqual(ret.description, 'test data') self.assertIs(ret.parent, self.nwbfile) self.assertEqual(self.nwbfile.get_scratch('test'), 2) def test_add_scratch_list(self): self.nwbfile.add_scratch([1, 2, 3, 4], name='test', description='test data') assert_array_equal(self.nwbfile.get_scratch('test'), np.array([1, 2, 3, 4])) def test_add_scratch_ndarray(self): self.nwbfile.add_scratch(np.array([1, 2, 3, 4]), name='test', description='test data') assert_array_equal(self.nwbfile.get_scratch('test'), np.array([1, 2, 3, 4])) def test_add_scratch_list_no_name(self): msg = ('A name is required for NWBFile.add_scratch when adding a scalar, numpy.ndarray, ' 'list, tuple, or pandas.DataFrame as scratch data.') with self.assertRaisesWith(ValueError, msg): self.nwbfile.add_scratch([1, 2, 3, 4]) def test_add_scratch_ndarray_no_description(self): msg = ('A description is required for NWBFile.add_scratch when adding a scalar, numpy.ndarray, ' 'list, tuple, or pandas.DataFrame as scratch data.') with self.assertRaisesWith(ValueError, msg): self.nwbfile.add_scratch(np.array([1, 2, 3, 4]), name='test') def test_add_scratch_dataframe(self): data = pd.DataFrame(data={'col1': [1, 2, 3, 4], 'col2': ['a', 'b', 'c', 'd']}) self.nwbfile.add_scratch(data, name='test', description='my_table') assert_array_equal(data.values, self.nwbfile.get_scratch('test').values) assert_array_equal(data.index.values, self.nwbfile.get_scratch('test').index.values) def test_add_scratch_dataframe_no_description(self): data = pd.DataFrame(data={'col1': [1, 2, 3, 4], 'col2': ['a', 'b', 'c', 'd']}) msg = ('A description is required for NWBFile.add_scratch when adding a scalar, numpy.ndarray, ' 'list, tuple, or pandas.DataFrame as scratch data.') with self.assertRaisesWith(ValueError, msg): self.nwbfile.add_scratch(data, name='test') def test_add_scratch_container(self): data = TimeSeries(name='test_ts', data=[1, 2, 3, 4, 5], unit='unit', timestamps=[1.1, 1.2, 1.3, 1.4, 1.5]) self.nwbfile.add_scratch(data) self.assertIs(self.nwbfile.get_scratch('test_ts'), data) self.assertIs(self.nwbfile.scratch['test_ts'], data) def test_add_scratch_container_name(self): data = TimeSeries(name='test_ts', data=[1, 2, 3, 4, 5], unit='unit', timestamps=[1.1, 1.2, 1.3, 1.4, 1.5]) msg = ('The name argument is ignored when adding an NWBContainer, ScratchData, or ' 'DynamicTable to scratch.') with self.assertWarnsWith(UserWarning, msg): self.nwbfile.add_scratch(data, name='Foo') self.assertIs(self.nwbfile.get_scratch('test_ts'), data) self.assertIs(self.nwbfile.scratch['test_ts'], data) def test_add_scratch_container_description(self): data = TimeSeries(name='test_ts', data=[1, 2, 3, 4, 5], unit='unit', timestamps=[1.1, 1.2, 1.3, 1.4, 1.5]) msg = ('The description argument is ignored when adding an NWBContainer, ScratchData, or ' 'DynamicTable to scratch.') with self.assertWarnsWith(UserWarning, msg): self.nwbfile.add_scratch(data, description='test scratch') self.assertIs(self.nwbfile.get_scratch('test_ts'), data) self.assertIs(self.nwbfile.scratch['test_ts'], data) def test_add_scratch_scratchdata(self): data = ScratchData(name='test', data=[1, 2, 3, 4, 5], description='test description') self.nwbfile.add_scratch(data) self.assertIs(data.parent, self.nwbfile) self.assertIs(self.nwbfile.get_scratch('test', convert=False), data) self.assertIs(self.nwbfile.scratch['test'], data) def test_add_scratch_dynamictable(self): data = DynamicTable(name='test', description='description') self.nwbfile.add_scratch(data) self.assertIs(self.nwbfile.get_scratch('test', convert=False), data) self.assertIs(self.nwbfile.scratch['test'], data) def test_get_scratch_list_convert_false(self): self.nwbfile.add_scratch([1, 2, 3, 4], name='test', description='test description') self.assertTrue(isinstance(self.nwbfile.get_scratch('test', convert=False), ScratchData)) self.assertTrue(isinstance(self.nwbfile.scratch['test'], ScratchData)) self.assertEqual(self.nwbfile.scratch['test'].data, [1, 2, 3, 4]) def test_get_scratch_df_convert_false(self): data = pd.DataFrame(data={'col1': [1, 2, 3, 4], 'col2': ['a', 'b', 'c', 'd']}) self.nwbfile.add_scratch(data, name='test', description='my_table') self.assertTrue(isinstance(self.nwbfile.get_scratch('test', convert=False), DynamicTable)) self.assertTrue(isinstance(self.nwbfile.scratch['test'], DynamicTable)) self.assertEqual(self.nwbfile.scratch['test'].description, 'my_table') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/unit/test_spec.py0000644000175100001730000000160714467767506016774 0ustar00runnerdocker''' Tests for NWB specific Spec classes This should really test to make sure neurodata_type_def and neurodata_type_inc gets mapped appropriately when constructors and methods are invoked ''' import json from pynwb.spec import NWBNamespaceBuilder, NWBRefSpec from pynwb.testing import TestCase class NWBNamespaceTest(TestCase): def test_constructor(self): self.ns_builder = NWBNamespaceBuilder("Frank Laboratory NWB Extensions", "franklab", version='0.1') class NWBRefSpecTests(TestCase): def test_constructor(self): spec = NWBRefSpec('TimeSeries', 'object') self.assertEqual(spec.target_type, 'TimeSeries') self.assertEqual(spec.reftype, 'object') json.dumps(spec) # to ensure there are no circular links def test_wrong_reference_type(self): with self.assertRaises(ValueError): NWBRefSpec('TimeSeries', 'unknownreftype') ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1692397558.5580275 pynwb-2.5.0/tests/validation/0000755000175100001730000000000014467767767015611 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/validation/__init__.py0000644000175100001730000000000014467767506017677 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tests/validation/test_validate.py0000644000175100001730000003645514467767506021017 0ustar00runnerdockerimport subprocess import re from unittest.mock import patch from io import StringIO from pynwb.testing import TestCase from pynwb import validate, NWBHDF5IO class TestValidateCLI(TestCase): # 1.0.2_nwbfile.nwb has no cached specifications # 1.0.3_nwbfile.nwb has cached "core" specification # 1.1.2_nwbfile.nwb has cached "core" and "hdmf-common" specifications # NOTE we use "coverage run -m pynwb.validate" instead of "python -m pynwb.validate" # so that we can both test pynwb.validate and compute code coverage from that test. # NOTE we also use "coverage run -p" which will generate a .coverage file with the # machine name, process id, and a random number appended to the filename to # simplify collecting and merging coverage data from multiple subprocesses. if "-p" # is not used, then each "coverage run" will overwrite the .coverage file from a # previous "coverage run". # NOTE the run_coverage.yml GitHub Action runs "python -m coverage combine" to # combine the individual coverage reports into one .coverage file. def test_validate_file_no_cache(self): """Test that validating a file with no cached spec against the core namespace succeeds.""" result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.0.2_nwbfile.nwb"], capture_output=True) stderr_regex = re.compile( r".*UserWarning: No cached namespaces found in tests/back_compat/1\.0\.2_nwbfile\.nwb\s*" r"warnings.warn\(msg\)\s*" r"The file tests/back_compat/1\.0\.2_nwbfile\.nwb has no cached namespace information\. " r"Falling back to PyNWB namespace information\.\s*" ) self.assertRegex(result.stderr.decode('utf-8'), stderr_regex) stdout_regex = re.compile( r"Validating tests/back_compat/1\.0\.2_nwbfile\.nwb against PyNWB namespace information using namespace " r"'core'\.\s* - no errors found\.\s*") self.assertRegex(result.stdout.decode('utf-8'), stdout_regex) def test_validate_file_no_cache_bad_ns(self): """Test that validating a file with no cached spec against a specified, unknown namespace fails.""" result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.0.2_nwbfile.nwb", "--ns", "notfound"], capture_output=True) stderr_regex = re.compile( r".*UserWarning: No cached namespaces found in tests/back_compat/1\.0\.2_nwbfile\.nwb\s*" r"warnings.warn\(msg\)\s*" r"The file tests/back_compat/1\.0\.2_nwbfile\.nwb has no cached namespace information\. " r"Falling back to PyNWB namespace information\.\s*" r"The namespace 'notfound' could not be found in PyNWB namespace information as only " r"\['core'\] is present\.\s*" ) self.assertRegex(result.stderr.decode('utf-8'), stderr_regex) self.assertEqual(result.stdout.decode('utf-8'), '') def test_validate_file_cached(self): """Test that validating a file with cached spec against its cached namespace succeeds.""" result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.1.2_nwbfile.nwb"], capture_output=True) self.assertEqual(result.stderr.decode('utf-8'), '') stdout_regex = re.compile( r"Validating tests/back_compat/1\.1\.2_nwbfile\.nwb against cached namespace information using namespace " r"'core'\.\s* - no errors found\.\s*") self.assertRegex(result.stdout.decode('utf-8'), stdout_regex) def test_validate_file_cached_bad_ns(self): """Test that validating a file with cached spec against a specified, unknown namespace fails.""" result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.1.2_nwbfile.nwb", "--ns", "notfound"], capture_output=True) stderr_regex = re.compile( r"The namespace 'notfound' could not be found in cached namespace information as only " r"\['core'\] is present\.\s*" ) self.assertRegex(result.stderr.decode('utf-8'), stderr_regex) self.assertEqual(result.stdout.decode('utf-8'), '') def test_validate_file_cached_extension(self): """Test that validating a file with cached spec against the cached namespaces succeeds.""" result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/2.1.0_nwbfile_with_extension.nwb"], capture_output=True) self.assertEqual(result.stderr.decode('utf-8'), '') stdout_regex = re.compile( r"Validating tests/back_compat/2\.1\.0_nwbfile_with_extension\.nwb against cached namespace information " r"using namespace 'ndx-testextension'\.\s* - no errors found\.\s*") self.assertRegex(result.stdout.decode('utf-8'), stdout_regex) def test_validate_file_cached_extension_pass_ns(self): """Test that validating a file with cached spec against the extension namespace succeeds.""" result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/2.1.0_nwbfile_with_extension.nwb", "--ns", "ndx-testextension"], capture_output=True) self.assertEqual(result.stderr.decode('utf-8'), '') stdout_regex = re.compile( r"Validating tests/back_compat/2\.1\.0_nwbfile_with_extension\.nwb against cached namespace information " r"using namespace 'ndx-testextension'\.\s* - no errors found\.\s*") self.assertRegex(result.stdout.decode('utf-8'), stdout_regex) def test_validate_file_cached_core(self): """Test that validating a file with cached spec against the core namespace succeeds.""" result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/2.1.0_nwbfile_with_extension.nwb", "--ns", "core"], capture_output=True) stdout_regex = re.compile( r"The namespace 'core' is included by the namespace 'ndx-testextension'. " r"Please validate against that namespace instead\.\s*" ) self.assertRegex(result.stderr.decode('utf-8'), stdout_regex) def test_validate_file_cached_hdmf_common(self): """Test that validating a file with cached spec against the hdmf-common namespace fails.""" result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.1.2_nwbfile.nwb", "--ns", "hdmf-common"], capture_output=True) stderr_regex = re.compile( r"The namespace 'hdmf-common' is included by the namespace 'core'\. Please validate against that " r"namespace instead\.\s*", ) self.assertRegex(result.stderr.decode('utf-8'), stderr_regex) def test_validate_file_cached_ignore(self): """Test that validating a file with cached spec against the core namespace succeeds.""" result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.1.2_nwbfile.nwb", "--no-cached-namespace"], capture_output=True) self.assertEqual(result.stderr.decode('utf-8'), '') stdout_regex = re.compile( r"Validating tests/back_compat/1\.1\.2_nwbfile\.nwb against PyNWB namespace information using namespace " r"'core'\.\s* - no errors found\.\s*") self.assertRegex(result.stdout.decode('utf-8'), stdout_regex) def test_validate_file_invalid(self): """Test that validating an invalid file outputs errors.""" result = subprocess.run( [ "coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.0.2_str_experimenter.nwb", "--no-cached-namespace" ], capture_output=True ) stderr_regex = re.compile( r" - found the following errors:\s*" r"root/general/experimenter \(general/experimenter\): incorrect shape - expected an array of shape " r"'\[None\]', got non-array data 'one experimenter'\s*" ) self.assertRegex(result.stderr.decode('utf-8'), stderr_regex) stdout_regex = re.compile( r"Validating tests/back_compat/1\.0\.2_str_experimenter\.nwb against PyNWB namespace information using " r"namespace 'core'\.\s*") self.assertRegex(result.stdout.decode('utf-8'), stdout_regex) def test_validate_file_list_namespaces_core(self): """Test listing namespaces from a file""" result = subprocess.run( [ "coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.1.2_nwbfile.nwb", "--list-namespaces" ], capture_output=True ) self.assertEqual(result.stderr.decode('utf-8'), '') stdout_regex = re.compile(r"core\s*") self.assertRegex(result.stdout.decode('utf-8'), stdout_regex) def test_validate_file_list_namespaces_extension(self): """Test listing namespaces from a file with an extension""" result = subprocess.run( [ "coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/2.1.0_nwbfile_with_extension.nwb", "--list-namespaces" ], capture_output=True ) self.assertEqual(result.stderr.decode('utf-8'), '') stdout_regex = re.compile(r"ndx-testextension\s*") self.assertRegex(result.stdout.decode('utf-8'), stdout_regex) class TestValidateFunction(TestCase): # 1.0.2_nwbfile.nwb has no cached specifications # 1.0.3_nwbfile.nwb has cached "core" specification # 1.1.2_nwbfile.nwb has cached "core" and "hdmf-common" specificaitions def test_validate_io_no_cache(self): """Test that validating a file with no cached spec against the core namespace succeeds.""" with NWBHDF5IO('tests/back_compat/1.0.2_nwbfile.nwb', 'r') as io: errors = validate(io) self.assertEqual(errors, []) def test_validate_io_no_cache_bad_ns(self): """Test that validating a file with no cached spec against a specified, unknown namespace fails.""" with NWBHDF5IO('tests/back_compat/1.0.2_nwbfile.nwb', 'r') as io: with self.assertRaisesWith(KeyError, "\"'notfound' not a namespace\""): validate(io, 'notfound') def test_validate_io_cached(self): """Test that validating a file with cached spec against its cached namespace succeeds.""" with NWBHDF5IO('tests/back_compat/1.1.2_nwbfile.nwb', 'r') as io: errors = validate(io) self.assertEqual(errors, []) def test_validate_io_cached_extension(self): """Test that validating a file with cached spec against its cached namespaces succeeds.""" with NWBHDF5IO('tests/back_compat/2.1.0_nwbfile_with_extension.nwb', 'r', load_namespaces=True) as io: errors = validate(io) self.assertEqual(errors, []) def test_validate_io_cached_extension_pass_ns(self): """Test that validating a file with cached extension spec against the extension namespace succeeds.""" with NWBHDF5IO('tests/back_compat/2.1.0_nwbfile_with_extension.nwb', 'r', load_namespaces=True) as io: errors = validate(io, 'ndx-testextension') self.assertEqual(errors, []) def test_validate_io_cached_core_with_io(self): """ For back-compatability, test that validating a file with cached extension spec against the core namespace succeeds when using the `io` + `namespace` keywords. """ with NWBHDF5IO( path='tests/back_compat/2.1.0_nwbfile_with_extension.nwb', mode='r', load_namespaces=True ) as io: results = validate(io=io, namespace="core") self.assertEqual(results, []) def test_validate_file_cached_extension(self): """ Test that validating a file with cached extension spec against the core namespace raises an error with the new CLI-mimicing paths keyword. """ nwbfile_path = "tests/back_compat/2.1.0_nwbfile_with_extension.nwb" with patch("sys.stderr", new=StringIO()) as fake_err: with patch("sys.stdout", new=StringIO()) as fake_out: results, status = validate(paths=[nwbfile_path], namespace="core", verbose=True) self.assertEqual(results, []) self.assertEqual(status, 1) self.assertEqual( fake_err.getvalue(), ( "The namespace 'core' is included by the namespace 'ndx-testextension'. " "Please validate against that namespace instead.\n" ) ) self.assertEqual(fake_out.getvalue(), "") def test_validate_file_cached_core(self): """ Test that validating a file with cached core spec with verbose=False. """ nwbfile_path = "tests/back_compat/1.1.2_nwbfile.nwb" with patch("sys.stderr", new=StringIO()) as fake_err: with patch("sys.stdout", new=StringIO()) as fake_out: results, status = validate(paths=[nwbfile_path], namespace="core") self.assertEqual(results, []) self.assertEqual(status, 0) self.assertEqual(fake_err.getvalue(), "") self.assertEqual(fake_out.getvalue(), "") def test_validate_file_cached_no_cache_bad_ns(self): """ Test that validating a file with no cached namespace, a namespace that is not found, and verbose=False. """ nwbfile_path = "tests/back_compat/1.0.2_nwbfile.nwb" with patch("sys.stderr", new=StringIO()) as fake_err: with patch("sys.stdout", new=StringIO()) as fake_out: results, status = validate(paths=[nwbfile_path], namespace="notfound") self.assertEqual(results, []) self.assertEqual(status, 1) stderr_regex = ( r"The namespace 'notfound' could not be found in PyNWB namespace information as only " r"\['core'\] is present.\n" ) self.assertRegex(fake_err.getvalue(), stderr_regex) self.assertEqual(fake_out.getvalue(), "") def test_validate_io_cached_bad_ns(self): """Test that validating a file with cached spec against a specified, unknown namespace fails.""" with NWBHDF5IO('tests/back_compat/1.1.2_nwbfile.nwb', 'r') as io: with self.assertRaisesWith(KeyError, "\"'notfound' not a namespace\""): validate(io, 'notfound') def test_validate_io_cached_hdmf_common(self): """Test that validating a file with cached spec against the hdmf-common namespace fails.""" with NWBHDF5IO('tests/back_compat/1.1.2_nwbfile.nwb', 'r') as io: # TODO this error should not be different from the error when using the validate script above msg = "builder must have data type defined with attribute 'data_type'" with self.assertRaisesWith(ValueError, msg): validate(io, 'hdmf-common') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/tox.ini0000644000175100001730000001205214467767506013617 0ustar00runnerdocker# Tox (https://tox.readthedocs.io/) is a tool for running tests # in multiple virtualenvs. This configuration file will run the # test suite on all supported python versions. To use it, "pip install tox" # and then run "tox" from this directory. [tox] envlist = py38, py39, py310, py311 requires = pip >= 22.0 [testenv] download = True usedevelop = True setenv = PYTHONDONTWRITEBYTECODE = 1 VIRTUALENV_PIP = 22.3.1 install_command = python -m pip install -U {opts} {packages} deps = -rrequirements-dev.txt -rrequirements.txt commands = python -m pip check # Check for conflicting packages python -m pip list python test.py -v # Env to create coverage report locally [testenv:localcoverage] basepython = python3.11 commands = python -m coverage run test.py --pynwb coverage html -d tests/coverage/htmlcov # Test with python 3.11; pinned dev and optional reqs [testenv:py311-optional] basepython = python3.11 install_command = python -m pip install {opts} {packages} deps = -rrequirements-dev.txt ; -rrequirements-opt.txt commands = {[testenv]commands} # Test with python 3.11; pinned dev and optional reqs; upgraded run reqs [testenv:py311-upgraded] basepython = python3.11 install_command = python -m pip install -U {opts} {packages} deps = -rrequirements-dev.txt ; -rrequirements-opt.txt commands = {[testenv]commands} # Test with python 3.11; pinned dev and optional reqs; upgraded, pre-release run reqs [testenv:py311-prerelease] basepython = python3.11 install_command = python -m pip install -U --pre {opts} {packages} deps = -rrequirements-dev.txt ; -rrequirements-opt.txt commands = {[testenv]commands} # Test with python 3.8; pinned dev reqs; minimum run reqs [testenv:py38-minimum] basepython = python3.8 deps = -rrequirements-dev.txt -rrequirements-min.txt commands = {[testenv]commands} # Envs that builds wheels and source distribution [testenv:build] commands = python -m pip install --upgrade build python -m build [testenv:build-py38] basepython = python3.8 commands = {[testenv:build]commands} [testenv:build-py39] basepython = python3.9 commands = {[testenv:build]commands} [testenv:build-py310] basepython = python3.10 commands = {[testenv:build]commands} [testenv:build-py311] basepython = python3.11 commands = {[testenv:build]commands} [testenv:build-py311-optional] basepython = python3.11 deps = -rrequirements-dev.txt ; -rrequirements-opt.txt commands = {[testenv:build]commands} [testenv:build-py311-upgraded] basepython = python3.11 install_command = python -m pip install -U {opts} {packages} deps = -rrequirements-dev.txt ; -rrequirements-opt.txt commands = {[testenv:build]commands} [testenv:build-py311-prerelease] basepython = python3.11 install_command = python -m pip install -U --pre {opts} {packages} deps = -rrequirements-dev.txt ; -rrequirements-opt.txt commands = {[testenv:build]commands} [testenv:build-py38-minimum] basepython = python3.8 deps = -rrequirements-dev.txt -rrequirements-min.txt commands = {[testenv:build]commands} # Envs that will test installation from a wheel [testenv:wheelinstall] deps = null commands = python -c "import pynwb" # Envs that will execute gallery tests that do not require ROS3 # Test with pinned dev, doc, run, and optional reqs [testenv:gallery] install_command = python -m pip install -U {opts} {packages} deps = -rrequirements.txt commands = python -m pip install -e . python -m pip install -r requirements-doc.txt # NOTE: allensdk (requirements-doc.txt) requires pynwb python -m pip check python -m pip list python test.py --example [testenv:gallery-py38] basepython = python3.8 deps = {[testenv:gallery]deps} commands = {[testenv:gallery]commands} [testenv:gallery-py39] basepython = python3.9 deps = {[testenv:gallery]deps} commands = {[testenv:gallery]commands} [testenv:gallery-py310] basepython = python3.10 deps = {[testenv:gallery]deps} commands = {[testenv:gallery]commands} [testenv:gallery-py311] basepython = python3.11 deps = {[testenv:gallery]deps} commands = {[testenv:gallery]commands} # Test with python 3.11; pinned dev, doc, and optional reqs; upgraded run reqs [testenv:gallery-py311-upgraded] basepython = python3.11 deps = -rrequirements-dev.txt commands = python -m pip install -U -e . python -m pip install -r requirements-doc.txt # NOTE: allensdk (requirements-doc.txt) requires pynwb python -m pip check python -m pip list python test.py --example # Test with python 3.11; pinned dev, doc, and optional reqs; pre-release run reqs [testenv:gallery-py311-prerelease] basepython = python3.11 deps = -rrequirements-dev.txt commands = python -m pip install -U --pre -e . python -m pip install -r requirements-doc.txt # NOTE: allensdk (requirements-doc.txt) requires pynwb python -m pip check python -m pip list python test.py --example # Test with python 3.8; pinned dev and doc reqs; minimum run reqs [testenv:gallery-py38-minimum] basepython = python3.8 deps = -rrequirements-min.txt commands = {[testenv:gallery]commands}././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1692397382.0 pynwb-2.5.0/versioneer.py0000644000175100001730000024211514467767506015044 0ustar00runnerdocker # Version: 0.26 """The Versioneer - like a rocketeer, but for versions. The Versioneer ============== * like a rocketeer, but for versions! * https://github.com/python-versioneer/python-versioneer * Brian Warner * License: Public Domain (Unlicense) * Compatible with: Python 3.7, 3.8, 3.9, 3.10 and pypy3 * [![Latest Version][pypi-image]][pypi-url] * [![Build Status][travis-image]][travis-url] This is a tool for managing a recorded version number in setuptools-based python projects. The goal is to remove the tedious and error-prone "update the embedded version string" step from your release process. Making a new release should be as easy as recording a new tag in your version-control system, and maybe making new tarballs. ## Quick Install Versioneer provides two installation modes. The "classic" vendored mode installs a copy of versioneer into your repository. The experimental build-time dependency mode is intended to allow you to skip this step and simplify the process of upgrading. ### Vendored mode * `pip install versioneer` to somewhere in your $PATH * add a `[tool.versioneer]` section to your `pyproject.toml or a `[versioneer]` section to your `setup.cfg` (see [Install](INSTALL.md)) * run `versioneer install --vendor` in your source tree, commit the results * verify version information with `python setup.py version` ### Build-time dependency mode * `pip install versioneer` to somewhere in your $PATH * add a `[tool.versioneer]` section to your `pyproject.toml or a `[versioneer]` section to your `setup.cfg` (see [Install](INSTALL.md)) * add `versioneer` to the `requires` key of the `build-system` table in `pyproject.toml`: ```toml [build-system] requires = ["setuptools", "versioneer"] build-backend = "setuptools.build_meta" ``` * run `versioneer install --no-vendor` in your source tree, commit the results * verify version information with `python setup.py version` ## Version Identifiers Source trees come from a variety of places: * a version-control system checkout (mostly used by developers) * a nightly tarball, produced by build automation * a snapshot tarball, produced by a web-based VCS browser, like github's "tarball from tag" feature * a release tarball, produced by "setup.py sdist", distributed through PyPI Within each source tree, the version identifier (either a string or a number, this tool is format-agnostic) can come from a variety of places: * ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows about recent "tags" and an absolute revision-id * the name of the directory into which the tarball was unpacked * an expanded VCS keyword ($Id$, etc) * a `_version.py` created by some earlier build step For released software, the version identifier is closely related to a VCS tag. Some projects use tag names that include more than just the version string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool needs to strip the tag prefix to extract the version identifier. For unreleased software (between tags), the version identifier should provide enough information to help developers recreate the same tree, while also giving them an idea of roughly how old the tree is (after version 1.2, before version 1.3). Many VCS systems can report a description that captures this, for example `git describe --tags --dirty --always` reports things like "0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the 0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has uncommitted changes). The version identifier is used for multiple purposes: * to allow the module to self-identify its version: `myproject.__version__` * to choose a name and prefix for a 'setup.py sdist' tarball ## Theory of Operation Versioneer works by adding a special `_version.py` file into your source tree, where your `__init__.py` can import it. This `_version.py` knows how to dynamically ask the VCS tool for version information at import time. `_version.py` also contains `$Revision$` markers, and the installation process marks `_version.py` to have this marker rewritten with a tag name during the `git archive` command. As a result, generated tarballs will contain enough information to get the proper version. To allow `setup.py` to compute a version too, a `versioneer.py` is added to the top level of your source tree, next to `setup.py` and the `setup.cfg` that configures it. This overrides several distutils/setuptools commands to compute the version when invoked, and changes `setup.py build` and `setup.py sdist` to replace `_version.py` with a small static file that contains just the generated version data. ## Installation See [INSTALL.md](./INSTALL.md) for detailed installation instructions. ## Version-String Flavors Code which uses Versioneer can learn about its version string at runtime by importing `_version` from your main `__init__.py` file and running the `get_versions()` function. From the "outside" (e.g. in `setup.py`), you can import the top-level `versioneer.py` and run `get_versions()`. Both functions return a dictionary with different flavors of version information: * `['version']`: A condensed version string, rendered using the selected style. This is the most commonly used value for the project's version string. The default "pep440" style yields strings like `0.11`, `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section below for alternative styles. * `['full-revisionid']`: detailed revision identifier. For Git, this is the full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac". * `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the commit date in ISO 8601 format. This will be None if the date is not available. * `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that this is only accurate if run in a VCS checkout, otherwise it is likely to be False or None * `['error']`: if the version string could not be computed, this will be set to a string describing the problem, otherwise it will be None. It may be useful to throw an exception in setup.py if this is set, to avoid e.g. creating tarballs with a version string of "unknown". Some variants are more useful than others. Including `full-revisionid` in a bug report should allow developers to reconstruct the exact code being tested (or indicate the presence of local changes that should be shared with the developers). `version` is suitable for display in an "about" box or a CLI `--version` output: it can be easily compared against release notes and lists of bugs fixed in various releases. The installer adds the following text to your `__init__.py` to place a basic version in `YOURPROJECT.__version__`: from ._version import get_versions __version__ = get_versions()['version'] del get_versions ## Styles The setup.cfg `style=` configuration controls how the VCS information is rendered into a version string. The default style, "pep440", produces a PEP440-compliant string, equal to the un-prefixed tag name for actual releases, and containing an additional "local version" section with more detail for in-between builds. For Git, this is TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags --dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and that this commit is two revisions ("+2") beyond the "0.11" tag. For released software (exactly equal to a known tag), the identifier will only contain the stripped tag, e.g. "0.11". Other styles are available. See [details.md](details.md) in the Versioneer source tree for descriptions. ## Debugging Versioneer tries to avoid fatal errors: if something goes wrong, it will tend to return a version of "0+unknown". To investigate the problem, run `setup.py version`, which will run the version-lookup code in a verbose mode, and will display the full contents of `get_versions()` (including the `error` string, which may help identify what went wrong). ## Known Limitations Some situations are known to cause problems for Versioneer. This details the most significant ones. More can be found on Github [issues page](https://github.com/python-versioneer/python-versioneer/issues). ### Subprojects Versioneer has limited support for source trees in which `setup.py` is not in the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are two common reasons why `setup.py` might not be in the root: * Source trees which contain multiple subprojects, such as [Buildbot](https://github.com/buildbot/buildbot), which contains both "master" and "slave" subprojects, each with their own `setup.py`, `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI distributions (and upload multiple independently-installable tarballs). * Source trees whose main purpose is to contain a C library, but which also provide bindings to Python (and perhaps other languages) in subdirectories. Versioneer will look for `.git` in parent directories, and most operations should get the right version string. However `pip` and `setuptools` have bugs and implementation details which frequently cause `pip install .` from a subproject directory to fail to find a correct version string (so it usually defaults to `0+unknown`). `pip install --editable .` should work correctly. `setup.py install` might work too. Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in some later version. [Bug #38](https://github.com/python-versioneer/python-versioneer/issues/38) is tracking this issue. The discussion in [PR #61](https://github.com/python-versioneer/python-versioneer/pull/61) describes the issue from the Versioneer side in more detail. [pip PR#3176](https://github.com/pypa/pip/pull/3176) and [pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve pip to let Versioneer work correctly. Versioneer-0.16 and earlier only looked for a `.git` directory next to the `setup.cfg`, so subprojects were completely unsupported with those releases. ### Editable installs with setuptools <= 18.5 `setup.py develop` and `pip install --editable .` allow you to install a project into a virtualenv once, then continue editing the source code (and test) without re-installing after every change. "Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a convenient way to specify executable scripts that should be installed along with the python package. These both work as expected when using modern setuptools. When using setuptools-18.5 or earlier, however, certain operations will cause `pkg_resources.DistributionNotFound` errors when running the entrypoint script, which must be resolved by re-installing the package. This happens when the install happens with one version, then the egg_info data is regenerated while a different version is checked out. Many setup.py commands cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into a different virtualenv), so this can be surprising. [Bug #83](https://github.com/python-versioneer/python-versioneer/issues/83) describes this one, but upgrading to a newer version of setuptools should probably resolve it. ## Updating Versioneer To upgrade your project to a new release of Versioneer, do the following: * install the new Versioneer (`pip install -U versioneer` or equivalent) * edit `setup.cfg` and `pyproject.toml`, if necessary, to include any new configuration settings indicated by the release notes. See [UPGRADING](./UPGRADING.md) for details. * re-run `versioneer install --[no-]vendor` in your source tree, to replace `SRC/_version.py` * commit any changed files ## Future Directions This tool is designed to make it easily extended to other version-control systems: all VCS-specific components are in separate directories like src/git/ . The top-level `versioneer.py` script is assembled from these components by running make-versioneer.py . In the future, make-versioneer.py will take a VCS name as an argument, and will construct a version of `versioneer.py` that is specific to the given VCS. It might also take the configuration arguments that are currently provided manually during installation by editing setup.py . Alternatively, it might go the other direction and include code from all supported VCS systems, reducing the number of intermediate scripts. ## Similar projects * [setuptools_scm](https://github.com/pypa/setuptools_scm/) - a non-vendored build-time dependency * [minver](https://github.com/jbweston/miniver) - a lightweight reimplementation of versioneer * [versioningit](https://github.com/jwodder/versioningit) - a PEP 518-based setuptools plugin ## License To make Versioneer easier to embed, all its code is dedicated to the public domain. The `_version.py` that it creates is also in the public domain. Specifically, both are released under the Creative Commons "Public Domain Dedication" license (CC0-1.0), as described in https://creativecommons.org/publicdomain/zero/1.0/ . [pypi-image]: https://img.shields.io/pypi/v/versioneer.svg [pypi-url]: https://pypi.python.org/pypi/versioneer/ [travis-image]: https://img.shields.io/travis/com/python-versioneer/python-versioneer.svg [travis-url]: https://travis-ci.com/github/python-versioneer/python-versioneer """ # pylint:disable=invalid-name,import-outside-toplevel,missing-function-docstring # pylint:disable=missing-class-docstring,too-many-branches,too-many-statements # pylint:disable=raise-missing-from,too-many-lines,too-many-locals,import-error # pylint:disable=too-few-public-methods,redefined-outer-name,consider-using-with # pylint:disable=attribute-defined-outside-init,too-many-arguments import configparser import errno import json import os import re import subprocess import sys from pathlib import Path from typing import Callable, Dict import functools try: import tomli have_tomli = True except ImportError: have_tomli = False class VersioneerConfig: """Container for Versioneer configuration parameters.""" def get_root(): """Get the project root directory. We require that all commands are run from the project root, i.e. the directory that contains setup.py, setup.cfg, and versioneer.py . """ root = os.path.realpath(os.path.abspath(os.getcwd())) setup_py = os.path.join(root, "setup.py") versioneer_py = os.path.join(root, "versioneer.py") if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): # allow 'python path/to/setup.py COMMAND' root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0]))) setup_py = os.path.join(root, "setup.py") versioneer_py = os.path.join(root, "versioneer.py") if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): err = ("Versioneer was unable to run the project root directory. " "Versioneer requires setup.py to be executed from " "its immediate directory (like 'python setup.py COMMAND'), " "or in a way that lets it use sys.argv[0] to find the root " "(like 'python path/to/setup.py COMMAND').") raise VersioneerBadRootError(err) try: # Certain runtime workflows (setup.py install/develop in a setuptools # tree) execute all dependencies in a single python process, so # "versioneer" may be imported multiple times, and python's shared # module-import table will cache the first one. So we can't use # os.path.dirname(__file__), as that will find whichever # versioneer.py was first imported, even in later projects. my_path = os.path.realpath(os.path.abspath(__file__)) me_dir = os.path.normcase(os.path.splitext(my_path)[0]) vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) if me_dir != vsr_dir and "VERSIONEER_PEP518" not in globals(): print("Warning: build in %s is using versioneer.py from %s" % (os.path.dirname(my_path), versioneer_py)) except NameError: pass return root def get_config_from_root(root): """Read the project setup.cfg file to determine Versioneer config.""" # This might raise OSError (if setup.cfg is missing), or # configparser.NoSectionError (if it lacks a [versioneer] section), or # configparser.NoOptionError (if it lacks "VCS="). See the docstring at # the top of versioneer.py for instructions on writing your setup.cfg . root = Path(root) pyproject_toml = root / "pyproject.toml" setup_cfg = root / "setup.cfg" section = None if pyproject_toml.exists() and have_tomli: try: with open(pyproject_toml, 'rb') as fobj: pp = tomli.load(fobj) section = pp['tool']['versioneer'] except (tomli.TOMLDecodeError, KeyError): pass if not section: parser = configparser.ConfigParser() with open(setup_cfg) as cfg_file: parser.read_file(cfg_file) parser.get("versioneer", "VCS") # raise error if missing section = parser["versioneer"] cfg = VersioneerConfig() cfg.VCS = section['VCS'] cfg.style = section.get("style", "") cfg.versionfile_source = section.get("versionfile_source") cfg.versionfile_build = section.get("versionfile_build") cfg.tag_prefix = section.get("tag_prefix") if cfg.tag_prefix in ("''", '""', None): cfg.tag_prefix = "" cfg.parentdir_prefix = section.get("parentdir_prefix") cfg.verbose = section.get("verbose") return cfg class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" # these dictionaries contain VCS-specific tools LONG_VERSION_PY: Dict[str, str] = {} HANDLERS: Dict[str, Dict[str, Callable]] = {} def register_vcs_handler(vcs, method): # decorator """Create decorator to mark a method as the handler of a VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" HANDLERS.setdefault(vcs, {})[method] = f return f return decorate def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) process = None popen_kwargs = {} if sys.platform == "win32": # This hides the console window if pythonw.exe is used startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW popen_kwargs["startupinfo"] = startupinfo for command in commands: try: dispcmd = str([command] + args) # remember shell=False, so use git.cmd on windows, not just git process = subprocess.Popen([command] + args, cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=(subprocess.PIPE if hide_stderr else None), **popen_kwargs) break except OSError: e = sys.exc_info()[1] if e.errno == errno.ENOENT: continue if verbose: print("unable to run %s" % dispcmd) print(e) return None, None else: if verbose: print("unable to find command, tried %s" % (commands,)) return None, None stdout = process.communicate()[0].strip().decode() if process.returncode != 0: if verbose: print("unable to run %s (error)" % dispcmd) print("stdout was %s" % stdout) return None, process.returncode return stdout, process.returncode LONG_VERSION_PY['git'] = r''' # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build # directories (produced by setup.py build) will contain a much shorter file # that just contains the computed version number. # This file is released into the public domain. # Generated by versioneer-0.26 # https://github.com/python-versioneer/python-versioneer """Git implementation of _version.py.""" import errno import os import re import subprocess import sys from typing import Callable, Dict import functools def get_keywords(): """Get the keywords needed to look up the version information.""" # these strings will be replaced by git during git-archive. # setup.py/versioneer.py will grep for the variable names, so they must # each be defined on a line of their own. _version.py will just call # get_keywords(). git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s" git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s" git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s" keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} return keywords class VersioneerConfig: """Container for Versioneer configuration parameters.""" def get_config(): """Create, populate and return the VersioneerConfig() object.""" # these strings are filled in when 'setup.py versioneer' creates # _version.py cfg = VersioneerConfig() cfg.VCS = "git" cfg.style = "%(STYLE)s" cfg.tag_prefix = "%(TAG_PREFIX)s" cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s" cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s" cfg.verbose = False return cfg class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" LONG_VERSION_PY: Dict[str, str] = {} HANDLERS: Dict[str, Dict[str, Callable]] = {} def register_vcs_handler(vcs, method): # decorator """Create decorator to mark a method as the handler of a VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: HANDLERS[vcs] = {} HANDLERS[vcs][method] = f return f return decorate def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) process = None popen_kwargs = {} if sys.platform == "win32": # This hides the console window if pythonw.exe is used startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW popen_kwargs["startupinfo"] = startupinfo for command in commands: try: dispcmd = str([command] + args) # remember shell=False, so use git.cmd on windows, not just git process = subprocess.Popen([command] + args, cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=(subprocess.PIPE if hide_stderr else None), **popen_kwargs) break except OSError: e = sys.exc_info()[1] if e.errno == errno.ENOENT: continue if verbose: print("unable to run %%s" %% dispcmd) print(e) return None, None else: if verbose: print("unable to find command, tried %%s" %% (commands,)) return None, None stdout = process.communicate()[0].strip().decode() if process.returncode != 0: if verbose: print("unable to run %%s (error)" %% dispcmd) print("stdout was %%s" %% stdout) return None, process.returncode return stdout, process.returncode def versions_from_parentdir(parentdir_prefix, root, verbose): """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both the project name and a version string. We will also support searching up two directory levels for an appropriately named parent directory """ rootdirs = [] for _ in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): return {"version": dirname[len(parentdir_prefix):], "full-revisionid": None, "dirty": False, "error": None, "date": None} rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: print("Tried directories %%s but none started with prefix %%s" %% (str(rootdirs), parentdir_prefix)) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @register_vcs_handler("git", "get_keywords") def git_get_keywords(versionfile_abs): """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. keywords = {} try: with open(versionfile_abs, "r") as fobj: for line in fobj: if line.strip().startswith("git_refnames ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["refnames"] = mo.group(1) if line.strip().startswith("git_full ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["full"] = mo.group(1) if line.strip().startswith("git_date ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["date"] = mo.group(1) except OSError: pass return keywords @register_vcs_handler("git", "keywords") def git_versions_from_keywords(keywords, tag_prefix, verbose): """Get version information from git keywords.""" if "refnames" not in keywords: raise NotThisMethod("Short version file found") date = keywords.get("date") if date is not None: # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because # it's been around since git-1.5.3, and it's too difficult to # discover which version we're using, or to work around using an # older one. date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) refnames = keywords["refnames"].strip() if refnames.startswith("$Format"): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") refs = {r.strip() for r in refnames.strip("()").split(",")} # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %%d # expansion behaves like git log --decorate=short and strips out the # refs/heads/ and refs/tags/ prefixes that would let us distinguish # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". tags = {r for r in refs if re.search(r'\d', r)} if verbose: print("discarding '%%s', no digits" %% ",".join(refs - tags)) if verbose: print("likely tags: %%s" %% ",".join(sorted(tags))) for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): r = ref[len(tag_prefix):] # Filter out refs that exactly match prefix or that don't start # with a number once the prefix is stripped (mostly a concern # when prefix is '') if not re.match(r'\d', r): continue if verbose: print("picking %%s" %% r) return {"version": r, "full-revisionid": keywords["full"].strip(), "dirty": False, "error": None, "date": date} # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") return {"version": "0+unknown", "full-revisionid": keywords["full"].strip(), "dirty": False, "error": "no suitable tags", "date": None} @register_vcs_handler("git", "pieces_from_vcs") def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* expanded, and _version.py hasn't already been rewritten with a short version string, meaning we're inside a checked out source tree. """ GITS = ["git"] if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] # GIT_DIR can interfere with correct operation of Versioneer. # It may be intended to be passed to the Versioneer-versioned project, # but that should not change where we get our version from. env = os.environ.copy() env.pop("GIT_DIR", None) runner = functools.partial(runner, env=env) _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=not verbose) if rc != 0: if verbose: print("Directory %%s not under git control" %% root) raise NotThisMethod("'git rev-parse --git-dir' returned error") # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) describe_out, rc = runner(GITS, [ "describe", "--tags", "--dirty", "--always", "--long", "--match", f"{tag_prefix}[[:digit:]]*" ], cwd=root) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() pieces = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], cwd=root) # --abbrev-ref was added in git-1.6.3 if rc != 0 or branch_name is None: raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") branch_name = branch_name.strip() if branch_name == "HEAD": # If we aren't exactly on a branch, pick a branch which represents # the current commit. If all else fails, we are on a branchless # commit. branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) # --contains was added in git-1.5.4 if rc != 0 or branches is None: raise NotThisMethod("'git branch --contains' returned error") branches = branches.split("\n") # Remove the first line if we're running detached if "(" in branches[0]: branches.pop(0) # Strip off the leading "* " from the list of branches. branches = [branch[2:] for branch in branches] if "master" in branches: branch_name = "master" elif not branches: branch_name = None else: # Pick the first branch that is returned. Good or bad. branch_name = branches[0] pieces["branch"] = branch_name # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out # look for -dirty suffix dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: git_describe = git_describe[:git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) if not mo: # unparsable. Maybe git-describe is misbehaving? pieces["error"] = ("unable to parse git-describe output: '%%s'" %% describe_out) return pieces # tag full_tag = mo.group(1) if not full_tag.startswith(tag_prefix): if verbose: fmt = "tag '%%s' doesn't start with prefix '%%s'" print(fmt %% (full_tag, tag_prefix)) pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'" %% (full_tag, tag_prefix)) return pieces pieces["closest-tag"] = full_tag[len(tag_prefix):] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) # commit: short hex revision ID pieces["short"] = mo.group(3) else: # HEX: no tags pieces["closest-tag"] = None out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) pieces["distance"] = len(out.split()) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() date = runner(GITS, ["show", "-s", "--format=%%ci", "HEAD"], cwd=root)[0].strip() # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces def plus_or_dot(pieces): """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" def render_pep440(pieces): """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty Exceptions: 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += plus_or_dot(pieces) rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_branch(pieces): """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . The ".dev0" means not master branch. Note that .dev0 sorts backwards (a feature branch will appear "older" than the master branch). Exceptions: 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: if pieces["branch"] != "master": rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0" if pieces["branch"] != "master": rendered += ".dev0" rendered += "+untagged.%%d.g%%s" %% (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def pep440_split_post(ver): """Split pep440 version string at the post-release segment. Returns the release segments before the post-release and the post-release version number (or -1 if no post-release segment is present). """ vc = str.split(ver, ".post") return vc[0], int(vc[1] or 0) if len(vc) == 2 else None def render_pep440_pre(pieces): """TAG[.postN.devDISTANCE] -- No -dirty. Exceptions: 1: no tags. 0.post0.devDISTANCE """ if pieces["closest-tag"]: if pieces["distance"]: # update the post release segment tag_version, post_version = pep440_split_post(pieces["closest-tag"]) rendered = tag_version if post_version is not None: rendered += ".post%%d.dev%%d" %% (post_version + 1, pieces["distance"]) else: rendered += ".post0.dev%%d" %% (pieces["distance"]) else: # no commits, use the tag as the version rendered = pieces["closest-tag"] else: # exception #1 rendered = "0.post0.dev%%d" %% pieces["distance"] return rendered def render_pep440_post(pieces): """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards (a dirty tree will appear "older" than the corresponding clean one), but you shouldn't be releasing software with -dirty anyways. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%%s" %% pieces["short"] else: # exception #1 rendered = "0.post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += "+g%%s" %% pieces["short"] return rendered def render_pep440_post_branch(pieces): """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . The ".dev0" means not master branch. Exceptions: 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%%d" %% pieces["distance"] if pieces["branch"] != "master": rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%%s" %% pieces["short"] if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0.post%%d" %% pieces["distance"] if pieces["branch"] != "master": rendered += ".dev0" rendered += "+g%%s" %% pieces["short"] if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_old(pieces): """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" else: # exception #1 rendered = "0.post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" return rendered def render_git_describe(pieces): """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render_git_describe_long(pieces): """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. The distance/hash is unconditional. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: return {"version": "unknown", "full-revisionid": pieces.get("long"), "dirty": None, "error": pieces["error"], "date": None} if not style or style == "default": style = "pep440" # the default if style == "pep440": rendered = render_pep440(pieces) elif style == "pep440-branch": rendered = render_pep440_branch(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) elif style == "pep440-post-branch": rendered = render_pep440_post_branch(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": rendered = render_git_describe(pieces) elif style == "git-describe-long": rendered = render_git_describe_long(pieces) else: raise ValueError("unknown style '%%s'" %% style) return {"version": rendered, "full-revisionid": pieces["long"], "dirty": pieces["dirty"], "error": None, "date": pieces.get("date")} def get_versions(): """Get version information or return default if unable to do so.""" # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have # __file__, we can work backwards from there to the root. Some # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which # case we can only use expanded keywords. cfg = get_config() verbose = cfg.verbose try: return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, verbose) except NotThisMethod: pass try: root = os.path.realpath(__file__) # versionfile_source is the relative path from the top of the source # tree (where the .git directory might live) to this file. Invert # this to find the root from __file__. for _ in cfg.versionfile_source.split('/'): root = os.path.dirname(root) except NameError: return {"version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to find root of source tree", "date": None} try: pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) return render(pieces, cfg.style) except NotThisMethod: pass try: if cfg.parentdir_prefix: return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) except NotThisMethod: pass return {"version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to compute version", "date": None} ''' @register_vcs_handler("git", "get_keywords") def git_get_keywords(versionfile_abs): """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. keywords = {} try: with open(versionfile_abs, "r") as fobj: for line in fobj: if line.strip().startswith("git_refnames ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["refnames"] = mo.group(1) if line.strip().startswith("git_full ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["full"] = mo.group(1) if line.strip().startswith("git_date ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["date"] = mo.group(1) except OSError: pass return keywords @register_vcs_handler("git", "keywords") def git_versions_from_keywords(keywords, tag_prefix, verbose): """Get version information from git keywords.""" if "refnames" not in keywords: raise NotThisMethod("Short version file found") date = keywords.get("date") if date is not None: # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because # it's been around since git-1.5.3, and it's too difficult to # discover which version we're using, or to work around using an # older one. date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) refnames = keywords["refnames"].strip() if refnames.startswith("$Format"): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") refs = {r.strip() for r in refnames.strip("()").split(",")} # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d # expansion behaves like git log --decorate=short and strips out the # refs/heads/ and refs/tags/ prefixes that would let us distinguish # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". tags = {r for r in refs if re.search(r'\d', r)} if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: print("likely tags: %s" % ",".join(sorted(tags))) for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): r = ref[len(tag_prefix):] # Filter out refs that exactly match prefix or that don't start # with a number once the prefix is stripped (mostly a concern # when prefix is '') if not re.match(r'\d', r): continue if verbose: print("picking %s" % r) return {"version": r, "full-revisionid": keywords["full"].strip(), "dirty": False, "error": None, "date": date} # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") return {"version": "0+unknown", "full-revisionid": keywords["full"].strip(), "dirty": False, "error": "no suitable tags", "date": None} @register_vcs_handler("git", "pieces_from_vcs") def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* expanded, and _version.py hasn't already been rewritten with a short version string, meaning we're inside a checked out source tree. """ GITS = ["git"] if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] # GIT_DIR can interfere with correct operation of Versioneer. # It may be intended to be passed to the Versioneer-versioned project, # but that should not change where we get our version from. env = os.environ.copy() env.pop("GIT_DIR", None) runner = functools.partial(runner, env=env) _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=not verbose) if rc != 0: if verbose: print("Directory %s not under git control" % root) raise NotThisMethod("'git rev-parse --git-dir' returned error") # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) describe_out, rc = runner(GITS, [ "describe", "--tags", "--dirty", "--always", "--long", "--match", f"{tag_prefix}[[:digit:]]*" ], cwd=root) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() pieces = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], cwd=root) # --abbrev-ref was added in git-1.6.3 if rc != 0 or branch_name is None: raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") branch_name = branch_name.strip() if branch_name == "HEAD": # If we aren't exactly on a branch, pick a branch which represents # the current commit. If all else fails, we are on a branchless # commit. branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) # --contains was added in git-1.5.4 if rc != 0 or branches is None: raise NotThisMethod("'git branch --contains' returned error") branches = branches.split("\n") # Remove the first line if we're running detached if "(" in branches[0]: branches.pop(0) # Strip off the leading "* " from the list of branches. branches = [branch[2:] for branch in branches] if "master" in branches: branch_name = "master" elif not branches: branch_name = None else: # Pick the first branch that is returned. Good or bad. branch_name = branches[0] pieces["branch"] = branch_name # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out # look for -dirty suffix dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: git_describe = git_describe[:git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) if not mo: # unparsable. Maybe git-describe is misbehaving? pieces["error"] = ("unable to parse git-describe output: '%s'" % describe_out) return pieces # tag full_tag = mo.group(1) if not full_tag.startswith(tag_prefix): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" % (full_tag, tag_prefix)) return pieces pieces["closest-tag"] = full_tag[len(tag_prefix):] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) # commit: short hex revision ID pieces["short"] = mo.group(3) else: # HEX: no tags pieces["closest-tag"] = None out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) pieces["distance"] = len(out.split()) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces def do_vcs_install(versionfile_source, ipy): """Git-specific installation logic for Versioneer. For Git, this means creating/changing .gitattributes to mark _version.py for export-subst keyword substitution. """ GITS = ["git"] if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] files = [versionfile_source] if ipy: files.append(ipy) if "VERSIONEER_PEP518" not in globals(): try: my_path = __file__ if my_path.endswith(".pyc") or my_path.endswith(".pyo"): my_path = os.path.splitext(my_path)[0] + ".py" versioneer_file = os.path.relpath(my_path) except NameError: versioneer_file = "versioneer.py" files.append(versioneer_file) present = False try: with open(".gitattributes", "r") as fobj: for line in fobj: if line.strip().startswith(versionfile_source): if "export-subst" in line.strip().split()[1:]: present = True break except OSError: pass if not present: with open(".gitattributes", "a+") as fobj: fobj.write(f"{versionfile_source} export-subst\n") files.append(".gitattributes") run_command(GITS, ["add", "--"] + files) def versions_from_parentdir(parentdir_prefix, root, verbose): """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both the project name and a version string. We will also support searching up two directory levels for an appropriately named parent directory """ rootdirs = [] for _ in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): return {"version": dirname[len(parentdir_prefix):], "full-revisionid": None, "dirty": False, "error": None, "date": None} rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: print("Tried directories %s but none started with prefix %s" % (str(rootdirs), parentdir_prefix)) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") SHORT_VERSION_PY = """ # This file was generated by 'versioneer.py' (0.26) from # revision-control system data, or from the parent directory name of an # unpacked source archive. Distribution tarballs contain a pre-generated copy # of this file. import json version_json = ''' %s ''' # END VERSION_JSON def get_versions(): return json.loads(version_json) """ def versions_from_file(filename): """Try to determine the version from _version.py if present.""" try: with open(filename) as f: contents = f.read() except OSError: raise NotThisMethod("unable to read _version.py") mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON", contents, re.M | re.S) if not mo: mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON", contents, re.M | re.S) if not mo: raise NotThisMethod("no version_json in _version.py") return json.loads(mo.group(1)) def write_to_version_file(filename, versions): """Write the given version number to the given _version.py file.""" os.unlink(filename) contents = json.dumps(versions, sort_keys=True, indent=1, separators=(",", ": ")) with open(filename, "w") as f: f.write(SHORT_VERSION_PY % contents) print("set %s to '%s'" % (filename, versions["version"])) def plus_or_dot(pieces): """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" def render_pep440(pieces): """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty Exceptions: 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += plus_or_dot(pieces) rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_branch(pieces): """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . The ".dev0" means not master branch. Note that .dev0 sorts backwards (a feature branch will appear "older" than the master branch). Exceptions: 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: if pieces["branch"] != "master": rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0" if pieces["branch"] != "master": rendered += ".dev0" rendered += "+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def pep440_split_post(ver): """Split pep440 version string at the post-release segment. Returns the release segments before the post-release and the post-release version number (or -1 if no post-release segment is present). """ vc = str.split(ver, ".post") return vc[0], int(vc[1] or 0) if len(vc) == 2 else None def render_pep440_pre(pieces): """TAG[.postN.devDISTANCE] -- No -dirty. Exceptions: 1: no tags. 0.post0.devDISTANCE """ if pieces["closest-tag"]: if pieces["distance"]: # update the post release segment tag_version, post_version = pep440_split_post(pieces["closest-tag"]) rendered = tag_version if post_version is not None: rendered += ".post%d.dev%d" % (post_version + 1, pieces["distance"]) else: rendered += ".post0.dev%d" % (pieces["distance"]) else: # no commits, use the tag as the version rendered = pieces["closest-tag"] else: # exception #1 rendered = "0.post0.dev%d" % pieces["distance"] return rendered def render_pep440_post(pieces): """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards (a dirty tree will appear "older" than the corresponding clean one), but you shouldn't be releasing software with -dirty anyways. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%s" % pieces["short"] else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += "+g%s" % pieces["short"] return rendered def render_pep440_post_branch(pieces): """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . The ".dev0" means not master branch. Exceptions: 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["branch"] != "master": rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%s" % pieces["short"] if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["branch"] != "master": rendered += ".dev0" rendered += "+g%s" % pieces["short"] if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_old(pieces): """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" return rendered def render_git_describe(pieces): """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render_git_describe_long(pieces): """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. The distance/hash is unconditional. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: return {"version": "unknown", "full-revisionid": pieces.get("long"), "dirty": None, "error": pieces["error"], "date": None} if not style or style == "default": style = "pep440" # the default if style == "pep440": rendered = render_pep440(pieces) elif style == "pep440-branch": rendered = render_pep440_branch(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) elif style == "pep440-post-branch": rendered = render_pep440_post_branch(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": rendered = render_git_describe(pieces) elif style == "git-describe-long": rendered = render_git_describe_long(pieces) else: raise ValueError("unknown style '%s'" % style) return {"version": rendered, "full-revisionid": pieces["long"], "dirty": pieces["dirty"], "error": None, "date": pieces.get("date")} class VersioneerBadRootError(Exception): """The project root directory is unknown or missing key files.""" def get_versions(verbose=False): """Get the project version from whatever source is available. Returns dict with two keys: 'version' and 'full'. """ if "versioneer" in sys.modules: # see the discussion in cmdclass.py:get_cmdclass() del sys.modules["versioneer"] root = get_root() cfg = get_config_from_root(root) assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg" handlers = HANDLERS.get(cfg.VCS) assert handlers, "unrecognized VCS '%s'" % cfg.VCS verbose = verbose or cfg.verbose assert cfg.versionfile_source is not None, \ "please set versioneer.versionfile_source" assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" versionfile_abs = os.path.join(root, cfg.versionfile_source) # extract version from first of: _version.py, VCS command (e.g. 'git # describe'), parentdir. This is meant to work for developers using a # source checkout, for users of a tarball created by 'setup.py sdist', # and for users of a tarball/zipball created by 'git archive' or github's # download-from-tag feature or the equivalent in other VCSes. get_keywords_f = handlers.get("get_keywords") from_keywords_f = handlers.get("keywords") if get_keywords_f and from_keywords_f: try: keywords = get_keywords_f(versionfile_abs) ver = from_keywords_f(keywords, cfg.tag_prefix, verbose) if verbose: print("got version from expanded keyword %s" % ver) return ver except NotThisMethod: pass try: ver = versions_from_file(versionfile_abs) if verbose: print("got version from file %s %s" % (versionfile_abs, ver)) return ver except NotThisMethod: pass from_vcs_f = handlers.get("pieces_from_vcs") if from_vcs_f: try: pieces = from_vcs_f(cfg.tag_prefix, root, verbose) ver = render(pieces, cfg.style) if verbose: print("got version from VCS %s" % ver) return ver except NotThisMethod: pass try: if cfg.parentdir_prefix: ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose) if verbose: print("got version from parentdir %s" % ver) return ver except NotThisMethod: pass if verbose: print("unable to compute version") return {"version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to compute version", "date": None} def get_version(): """Get the short version string for this project.""" return get_versions()["version"] def get_cmdclass(cmdclass=None): """Get the custom setuptools subclasses used by Versioneer. If the package uses a different cmdclass (e.g. one from numpy), it should be provide as an argument. """ if "versioneer" in sys.modules: del sys.modules["versioneer"] # this fixes the "python setup.py develop" case (also 'install' and # 'easy_install .'), in which subdependencies of the main project are # built (using setup.py bdist_egg) in the same python process. Assume # a main project A and a dependency B, which use different versions # of Versioneer. A's setup.py imports A's Versioneer, leaving it in # sys.modules by the time B's setup.py is executed, causing B to run # with the wrong versioneer. Setuptools wraps the sub-dep builds in a # sandbox that restores sys.modules to it's pre-build state, so the # parent is protected against the child's "import versioneer". By # removing ourselves from sys.modules here, before the child build # happens, we protect the child from the parent's versioneer too. # Also see https://github.com/python-versioneer/python-versioneer/issues/52 cmds = {} if cmdclass is None else cmdclass.copy() # we add "version" to setuptools from setuptools import Command class cmd_version(Command): description = "report generated version string" user_options = [] boolean_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): vers = get_versions(verbose=True) print("Version: %s" % vers["version"]) print(" full-revisionid: %s" % vers.get("full-revisionid")) print(" dirty: %s" % vers.get("dirty")) print(" date: %s" % vers.get("date")) if vers["error"]: print(" error: %s" % vers["error"]) cmds["version"] = cmd_version # we override "build_py" in setuptools # # most invocation pathways end up running build_py: # distutils/build -> build_py # distutils/install -> distutils/build ->.. # setuptools/bdist_wheel -> distutils/install ->.. # setuptools/bdist_egg -> distutils/install_lib -> build_py # setuptools/install -> bdist_egg ->.. # setuptools/develop -> ? # pip install: # copies source tree to a tempdir before running egg_info/etc # if .git isn't copied too, 'git describe' will fail # then does setup.py bdist_wheel, or sometimes setup.py install # setup.py egg_info -> ? # pip install -e . and setuptool/editable_wheel will invoke build_py # but the build_py command is not expected to copy any files. # we override different "build_py" commands for both environments if 'build_py' in cmds: _build_py = cmds['build_py'] else: from setuptools.command.build_py import build_py as _build_py class cmd_build_py(_build_py): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() _build_py.run(self) if getattr(self, "editable_mode", False): # During editable installs `.py` and data files are # not copied to build_lib return # now locate _version.py in the new build/ directory and replace # it with an updated value if cfg.versionfile_build: target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) cmds["build_py"] = cmd_build_py if 'build_ext' in cmds: _build_ext = cmds['build_ext'] else: from setuptools.command.build_ext import build_ext as _build_ext class cmd_build_ext(_build_ext): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() _build_ext.run(self) if self.inplace: # build_ext --inplace will only build extensions in # build/lib<..> dir with no _version.py to write to. # As in place builds will already have a _version.py # in the module dir, we do not need to write one. return # now locate _version.py in the new build/ directory and replace # it with an updated value target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) if not os.path.exists(target_versionfile): print(f"Warning: {target_versionfile} does not exist, skipping " "version update. This can happen if you are running build_ext " "without first running build_py.") return print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) cmds["build_ext"] = cmd_build_ext if "cx_Freeze" in sys.modules: # cx_freeze enabled? from cx_Freeze.dist import build_exe as _build_exe # nczeczulin reports that py2exe won't like the pep440-style string # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. # setup(console=[{ # "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION # "product_version": versioneer.get_version(), # ... class cmd_build_exe(_build_exe): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() target_versionfile = cfg.versionfile_source print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) _build_exe.run(self) os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] f.write(LONG % {"DOLLAR": "$", "STYLE": cfg.style, "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, }) cmds["build_exe"] = cmd_build_exe del cmds["build_py"] if 'py2exe' in sys.modules: # py2exe enabled? try: from py2exe.setuptools_buildexe import py2exe as _py2exe except ImportError: from py2exe.distutils_buildexe import py2exe as _py2exe class cmd_py2exe(_py2exe): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() target_versionfile = cfg.versionfile_source print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) _py2exe.run(self) os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] f.write(LONG % {"DOLLAR": "$", "STYLE": cfg.style, "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, }) cmds["py2exe"] = cmd_py2exe # sdist farms its file list building out to egg_info if 'egg_info' in cmds: _sdist = cmds['egg_info'] else: from setuptools.command.egg_info import egg_info as _egg_info class cmd_egg_info(_egg_info): def find_sources(self): # egg_info.find_sources builds the manifest list and writes it # in one shot super().find_sources() # Modify the filelist and normalize it root = get_root() cfg = get_config_from_root(root) self.filelist.append('versioneer.py') if cfg.versionfile_source: # There are rare cases where versionfile_source might not be # included by default, so we must be explicit self.filelist.append(cfg.versionfile_source) self.filelist.sort() self.filelist.remove_duplicates() # The write method is hidden in the manifest_maker instance that # generated the filelist and was thrown away # We will instead replicate their final normalization (to unicode, # and POSIX-style paths) from setuptools import unicode_utils normalized = [unicode_utils.filesys_decode(f).replace(os.sep, '/') for f in self.filelist.files] manifest_filename = os.path.join(self.egg_info, 'SOURCES.txt') with open(manifest_filename, 'w') as fobj: fobj.write('\n'.join(normalized)) cmds['egg_info'] = cmd_egg_info # we override different "sdist" commands for both environments if 'sdist' in cmds: _sdist = cmds['sdist'] else: from setuptools.command.sdist import sdist as _sdist class cmd_sdist(_sdist): def run(self): versions = get_versions() self._versioneer_generated_versions = versions # unless we update this, the command will keep using the old # version self.distribution.metadata.version = versions["version"] return _sdist.run(self) def make_release_tree(self, base_dir, files): root = get_root() cfg = get_config_from_root(root) _sdist.make_release_tree(self, base_dir, files) # now locate _version.py in the new base_dir directory # (remembering that it may be a hardlink) and replace it with an # updated value target_versionfile = os.path.join(base_dir, cfg.versionfile_source) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, self._versioneer_generated_versions) cmds["sdist"] = cmd_sdist return cmds CONFIG_ERROR = """ setup.cfg is missing the necessary Versioneer configuration. You need a section like: [versioneer] VCS = git style = pep440 versionfile_source = src/myproject/_version.py versionfile_build = myproject/_version.py tag_prefix = parentdir_prefix = myproject- You will also need to edit your setup.py to use the results: import versioneer setup(version=versioneer.get_version(), cmdclass=versioneer.get_cmdclass(), ...) Please read the docstring in ./versioneer.py for configuration instructions, edit setup.cfg, and re-run the installer or 'python versioneer.py setup'. """ SAMPLE_CONFIG = """ # See the docstring in versioneer.py for instructions. Note that you must # re-run 'versioneer.py setup' after changing this section, and commit the # resulting files. [versioneer] #VCS = git #style = pep440 #versionfile_source = #versionfile_build = #tag_prefix = #parentdir_prefix = """ OLD_SNIPPET = """ from ._version import get_versions __version__ = get_versions()['version'] del get_versions """ INIT_PY_SNIPPET = """ from . import {0} __version__ = {0}.get_versions()['version'] """ def do_setup(): """Do main VCS-independent setup function for installing Versioneer.""" root = get_root() try: cfg = get_config_from_root(root) except (OSError, configparser.NoSectionError, configparser.NoOptionError) as e: if isinstance(e, (OSError, configparser.NoSectionError)): print("Adding sample versioneer config to setup.cfg", file=sys.stderr) with open(os.path.join(root, "setup.cfg"), "a") as f: f.write(SAMPLE_CONFIG) print(CONFIG_ERROR, file=sys.stderr) return 1 print(" creating %s" % cfg.versionfile_source) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] f.write(LONG % {"DOLLAR": "$", "STYLE": cfg.style, "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, }) ipy = os.path.join(os.path.dirname(cfg.versionfile_source), "__init__.py") if os.path.exists(ipy): try: with open(ipy, "r") as f: old = f.read() except OSError: old = "" module = os.path.splitext(os.path.basename(cfg.versionfile_source))[0] snippet = INIT_PY_SNIPPET.format(module) if OLD_SNIPPET in old: print(" replacing boilerplate in %s" % ipy) with open(ipy, "w") as f: f.write(old.replace(OLD_SNIPPET, snippet)) elif snippet not in old: print(" appending to %s" % ipy) with open(ipy, "a") as f: f.write(snippet) else: print(" %s unmodified" % ipy) else: print(" %s doesn't exist, ok" % ipy) ipy = None # Make VCS-specific changes. For git, this means creating/changing # .gitattributes to mark _version.py for export-subst keyword # substitution. do_vcs_install(cfg.versionfile_source, ipy) return 0 def scan_setup_py(): """Validate the contents of setup.py against Versioneer's expectations.""" found = set() setters = False errors = 0 with open("setup.py", "r") as f: for line in f.readlines(): if "import versioneer" in line: found.add("import") if "versioneer.get_cmdclass()" in line: found.add("cmdclass") if "versioneer.get_version()" in line: found.add("get_version") if "versioneer.VCS" in line: setters = True if "versioneer.versionfile_source" in line: setters = True if len(found) != 3: print("") print("Your setup.py appears to be missing some important items") print("(but I might be wrong). Please make sure it has something") print("roughly like the following:") print("") print(" import versioneer") print(" setup( version=versioneer.get_version(),") print(" cmdclass=versioneer.get_cmdclass(), ...)") print("") errors += 1 if setters: print("You should remove lines like 'versioneer.VCS = ' and") print("'versioneer.versionfile_source = ' . This configuration") print("now lives in setup.cfg, and should be removed from setup.py") print("") errors += 1 return errors def setup_command(): """Set up Versioneer and exit with appropriate error code.""" errors = do_setup() errors += scan_setup_py() sys.exit(1 if errors else 0) if __name__ == "__main__": cmd = sys.argv[1] if cmd == "setup": setup_command()