diff -Nru neo-0.10.0/AUTHORS neo-0.10.2/AUTHORS --- neo-0.10.0/AUTHORS 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/AUTHORS 2017-09-13 07:28:41.000000000 +0000 @@ -0,0 +1 @@ +See doc/source/authors.rst diff -Nru neo-0.10.0/CITATION.txt neo-0.10.2/CITATION.txt --- neo-0.10.0/CITATION.txt 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/CITATION.txt 2020-08-28 09:11:20.000000000 +0000 @@ -0,0 +1,21 @@ +To cite Neo in publications, please use: + + Garcia S., Guarino D., Jaillet F., Jennings T.R., Pröpper R., Rautenberg P.L., + Rodgers C., Sobolev A.,Wachtler T., Yger P. and Davison A.P. (2014) + Neo: an object model for handling electrophysiology data in multiple formats. + Frontiers in Neuroinformatics 8:10: doi:10.3389/fninf.2014.00010 + +A BibTeX entry for LaTeX users is:: + + @article{neo14, + author = {Garcia S. and Guarino D. and Jaillet F. and Jennings T.R. and Pröpper R. and + Rautenberg P.L. and Rodgers C. and Sobolev A. and Wachtler T. and Yger P. + and Davison A.P.}, + doi = {10.3389/fninf.2014.00010}, + full_text = {http://www.frontiersin.org/Journal/10.3389/fninf.2014.00010/abstract}, + journal = {Frontiers in Neuroinformatics}, + month = {February}, + title = {Neo: an object model for handling electrophysiology data in multiple formats}, + volume = {8:10}, + year = {2014} + } diff -Nru neo-0.10.0/CODE_OF_CONDUCT.md neo-0.10.2/CODE_OF_CONDUCT.md --- neo-0.10.0/CODE_OF_CONDUCT.md 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/CODE_OF_CONDUCT.md 2018-11-22 16:35:41.000000000 +0000 @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at neo-maintainers@protonmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff -Nru neo-0.10.0/CONTRIBUTING.md neo-0.10.2/CONTRIBUTING.md --- neo-0.10.0/CONTRIBUTING.md 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/CONTRIBUTING.md 2018-11-22 16:35:41.000000000 +0000 @@ -0,0 +1 @@ +See http://neo.readthedocs.io/en/latest/developers_guide.html diff -Nru neo-0.10.0/debian/changelog neo-0.10.2/debian/changelog --- neo-0.10.0/debian/changelog 2022-02-17 15:20:51.000000000 +0000 +++ neo-0.10.2/debian/changelog 2022-05-05 14:25:32.000000000 +0000 @@ -1,3 +1,13 @@ +neo (0.10.2-1) unstable; urgency=medium + + * Team upload. + * New upstream version + * d/copyright: update the file to reflect current licensing terms. + The package notably moved from BSD-2-clause to BSD-3-clause licensing + terms. Also updated the list of debian contributors from git log. + + -- Étienne Mollier Thu, 05 May 2022 16:25:32 +0200 + neo (0.10.0-1) unstable; urgency=medium * Team upload. diff -Nru neo-0.10.0/debian/copyright neo-0.10.2/debian/copyright --- neo-0.10.0/debian/copyright 2022-02-17 15:20:51.000000000 +0000 +++ neo-0.10.2/debian/copyright 2022-05-05 14:25:32.000000000 +0000 @@ -4,12 +4,11 @@ Source: http://neuralensemble.org/neo Files: * -Copyright: 2010-2012 Samuel Garcia, Andrew Davison, Chris Rodgers, Pierre Yger, - Yann Mahnoun, Luc Estabanez, Andrey Sobolev, Thierry Brizzi, Florent Jaillet, - Philipp Rautenberg, Thomas Wachtler, +Copyright: 2010-2022 Neo authors and contributors License: BSD-2-clause +Comment: see doc/source/authors.rst in source code for full contributors list. -Files: neo/io/axonio.py +Files: neo/rawio/axonrawio.py Copyright: 2009, Forrest Collman 2004, Harald Hentschke License: BSD-2-clause @@ -17,10 +16,46 @@ This code is actually a port of a MATLAB implementation originally written by the persons listed above. +Files: neo/io/nixio.py + neo/test/iotest/test_nixio.py +Copyright: 2016, German Neuroinformatics Node (G-Node) +License: BSD-3-clause +Comment: + BSD code is suspected to derive from nixpy[1], which is BSD-3-clause licensed. + . + [1]: https://github.com/G-Node/nixpy + Files: debian/* -Copyright: 2012 Michael Hanke +Copyright: 2012-2015 Michael Hanke + 2012-2019 Yaroslav Halchenko + 2020-2022 Andreas Tille + 2022 Étienne Mollier License: BSD-2-clause +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * 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. + * Neither the names of the copyright holders nor the names of the + 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 HOLDER 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. + License: BSD-2-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff -Nru neo-0.10.0/doc/requirements_docs.txt neo-0.10.2/doc/requirements_docs.txt --- neo-0.10.0/doc/requirements_docs.txt 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/doc/requirements_docs.txt 2022-02-11 14:04:12.000000000 +0000 @@ -0,0 +1,3 @@ +docutils<0.18 +numpy>=1.16.1 +quantities>=0.12.1 diff -Nru neo-0.10.0/doc/requirements_rtd.txt neo-0.10.2/doc/requirements_rtd.txt --- neo-0.10.0/doc/requirements_rtd.txt 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/doc/requirements_rtd.txt 2020-12-14 15:52:22.000000000 +0000 @@ -0,0 +1,3 @@ +pillow +sphinx-gallery +matplotlib diff -Nru neo-0.10.0/doc/source/authors.rst.orig neo-0.10.2/doc/source/authors.rst.orig --- neo-0.10.0/doc/source/authors.rst.orig 2021-03-04 10:55:41.000000000 +0000 +++ neo-0.10.2/doc/source/authors.rst.orig 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -======================== -Authors and contributors -======================== - -The following people have contributed code and/or ideas to the current version -of Neo. The institutional affiliations are those at the time of the contribution, -and may not be the current affiliation of a contributor. - -* Samuel Garcia [1] -* Andrew Davison [2, 21] -* Chris Rodgers [3] -* Pierre Yger [2] -* Yann Mahnoun [4] -* Luc Estabanez [2] -* Andrey Sobolev [5] -* Thierry Brizzi [2] -* Florent Jaillet [6] -* Philipp Rautenberg [5] -* Thomas Wachtler [5] -* Cyril Dejean [7] -* Robert Pröpper [8] -* Domenico Guarino [2] -* Achilleas Koutsou [5] -* Erik Li [9] -* Georg Raiser [10] -* Joffrey Gonin [2] -* Kyler Brown [?] -* Mikkel Elle Lepperød [11] -* C Daniel Meliza [12] -* Julia Sprenger [13] -* Maximilian Schmidt [13] -* Johanna Senk [13] -* Carlos Canova [13] -* Hélissande Fragnaud [2] -* Mark Hollenbeck [14] -* Mieszko Grodzicki -* Rick Gerkin [15] -* Matthieu Sénoville [2] -* Chadwick Boulay [16] -* Björn Müller [13] -* William Hart [17] -* erikli(github) -* Jeffrey Gill [18] -* Lucas (lkoelman@github) -* Mark Histed -* Mike Sintsov [19] -* Scott W Harden [20] -* Chek Yin Choi (hkchekc@github) -* Corentin Fragnaud [21] -* Alexander Kleinjohann -* Christian Kothe -* rishidhingra@github -* Hugo van Kemenade -* Aitor Morales-Gregorio [13] -* Peter N Steinmetz [22] -<<<<<<< HEAD -* Shashwat Sridhar -* Alessio Buccino [23] -======= -* Regimantas Jurkus [13] ->>>>>>> c8d42afb439ecd71eff1cd61d24dadec055070f2 - -1. Centre de Recherche en Neuroscience de Lyon, CNRS UMR5292 - INSERM U1028 - Universite Claude Bernard Lyon 1 -2. Unité de Neuroscience, Information et Complexité, CNRS UPR 3293, Gif-sur-Yvette, France -3. University of California, Berkeley -4. Laboratoire de Neurosciences Intégratives et Adaptatives, CNRS UMR 6149 - Université de Provence, Marseille, France -5. G-Node, Ludwig-Maximilians-Universität, Munich, Germany -6. Institut de Neurosciences de la Timone, CNRS UMR 7289 - Université d'Aix-Marseille, Marseille, France -7. Centre de Neurosciences Integratives et Cognitives, UMR 5228 - CNRS - Université Bordeaux I - Université Bordeaux II -8. Neural Information Processing Group, TU Berlin, Germany -9. Department of Neurobiology & Anatomy, Drexel University College of Medicine, Philadelphia, PA, USA -10. University of Konstanz, Konstanz, Germany -11. Centre for Integrative Neuroplasticity (CINPLA), University of Oslo, Norway -12. University of Virginia -13. INM-6, Forschungszentrum Jülich, Germany -14. University of Texas at Austin -15. Arizona State University -16. Ottawa Hospital Research Institute, Canada -17. Swinburne University of Technology, Australia -18. Case Western Reserve University (CWRU) · Department of Biology -19. IAL Developmental Neurobiology, Kazan Federal University, Kazan, Russia -20. Harden Technologies, LLC -21. Institut des Neurosciences Paris-Saclay, CNRS UMR 9197 - Université Paris-Sud, Gif-sur-Yvette, France -22. Neurtex Brain Research Institute, Dallas, TX, USAs -23. Bio Engineering Laboratory, DBSSE, ETH, Basel, Switzerland - -If we've somehow missed you off the list we're very sorry - please let us know. - - -Acknowledgements ----------------- - -.. image:: https://www.braincouncil.eu/wp-content/uploads/2018/11/wsi-imageoptim-EU-Logo.jpg - :alt: "EU Logo" - :height: 104px - :width: 156px - :align: right - -Neo was developed in part in the Human Brain Project, -funded from the European Union's Horizon 2020 Framework Programme for Research and Innovation -under Specific Grant Agreements No. 720270 and No. 785907 (Human Brain Project SGA1 and SGA2). diff -Nru neo-0.10.0/doc/source/conf.py neo-0.10.2/doc/source/conf.py --- neo-0.10.0/doc/source/conf.py 2021-07-27 08:39:25.000000000 +0000 +++ neo-0.10.2/doc/source/conf.py 2022-03-08 09:34:55.000000000 +0000 @@ -51,7 +51,7 @@ # General information about the project. project = 'Neo' -copyright = '2010-2021, ' + AUTHORS +copyright = '2010-2022, ' + AUTHORS # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff -Nru neo-0.10.0/doc/source/developers_guide.rst neo-0.10.2/doc/source/developers_guide.rst --- neo-0.10.0/doc/source/developers_guide.rst 2021-06-28 16:29:12.000000000 +0000 +++ neo-0.10.2/doc/source/developers_guide.rst 2022-02-11 14:04:12.000000000 +0000 @@ -235,8 +235,7 @@ $ git push --tags upstream -To upload the package to `PyPI`_ (currently Samuel Garcia, Andrew Davison, -Michael Denker and Julia Sprenger have the necessary permissions to do this):: +To upload the package to `PyPI`_ (the members of the `maintainers team`_ have the necessary permissions to do this):: $ twine upload dist/neo-0.X.Y.tar.gz @@ -253,6 +252,11 @@ See :ref:`io_dev_guide` for implementation of a new IO. +Project governance +------------------ + +The :doc:`governance` document describes how decisions about the project are taken. + .. _Python: https://www.python.org @@ -276,3 +280,4 @@ .. _pep8: https://pypi.org/project/pep8/ .. _flake8: https://pypi.org/project/flake8/ .. _pyflakes: https://pypi.org/project/pyflakes/ +.. _`maintainers team`: https://github.com/orgs/NeuralEnsemble/teams/neo-maintainers \ No newline at end of file diff -Nru neo-0.10.0/doc/source/developers_guide.rst.orig neo-0.10.2/doc/source/developers_guide.rst.orig --- neo-0.10.0/doc/source/developers_guide.rst.orig 2019-09-30 08:31:24.000000000 +0000 +++ neo-0.10.2/doc/source/developers_guide.rst.orig 1970-01-01 00:00:00.000000000 +0000 @@ -1,309 +0,0 @@ -================= -Developers' guide -================= - -These instructions are for developing on a Unix-like platform, e.g. Linux or -macOS, with the bash shell. If you develop on Windows, please get in touch. - - -Mailing lists -------------- - -General discussion of Neo development takes place in the `NeuralEnsemble Google -group`_. - -Discussion of issues specific to a particular ticket in the issue tracker -should take place on the tracker. - - -Using the issue tracker ------------------------ - -If you find a bug in Neo, please create a new ticket on the `issue tracker`_, -setting the type to "defect". -Choose a name that is as specific as possible to the problem you've found, and -in the description give as much information as you think is necessary to -recreate the problem. The best way to do this is to create the shortest -possible Python script that demonstrates the problem, and attach the file to -the ticket. - -If you have an idea for an improvement to Neo, create a ticket with type -"enhancement". If you already have an implementation of the idea, create a -patch (see below) and attach it to the ticket. - -To keep track of changes to the code and to tickets, you can register for -a GitHub account and then set to watch the repository at `GitHub Repository`_ -(see https://help.github.com/articles/watching-repositories/). - -Requirements ------------- - -<<<<<<< HEAD - * Python_ 2.7, 3.4 or later - * numpy_ >= 1.10.0 - * quantities_ >= 0.12.1 - * nose_ >= 1.1.2 (for running tests) - * Sphinx_ (for building documentation) -======= - * Python_ 2.7, 3.5 or later - * numpy_ >= 1.7.1 - * quantities_ >= 0.9.0 - * nose_ >= 0.11.1 (for running tests) - * Sphinx_ >= 0.6.4 (for building documentation) - * (optional) tox_ >= 0.9 (makes it easier to test with multiple Python versions) ->>>>>>> 81b676c0b72ad4ae7d05321e07d9d1e73480b074 - * (optional) coverage_ >= 2.85 (for measuring test coverage) - * (optional) scipy >= 0.12 (for MatlabIO) - * (optional) h5py >= 2.5 (for KwikIO, NeoHdf5IO) - * (optional) nixio (for NixIO) - * (optional) pillow (for TiffIO) - -We strongly recommend you develop within a virtual environment (from virtualenv, venv or conda). -It is best to have at least one virtual environment with Python 2.7 and one with Python 3.x. - -Getting the source code ------------------------ - -We use the Git version control system. The best way to contribute is through -GitHub_. You will first need a GitHub account, and you should then fork the -repository at `GitHub Repository`_ -(see http://help.github.com/fork-a-repo/). - -To get a local copy of the repository:: - - $ cd /some/directory - $ git clone git@github.com:/python-neo.git - -Now you need to make sure that the ``neo`` package is on your PYTHONPATH. -You can do this either by installing Neo:: - - $ cd python-neo - $ python setup.py install - $ python3 setup.py install - -(if you do this, you will have to re-run ``setup.py install`` any time you make -changes to the code) *or* by creating symbolic links from somewhere on your -PYTHONPATH, for example:: - - $ ln -s python-neo/neo - $ export PYTHONPATH=/some/directory:${PYTHONPATH} - -An alternate solution is to install Neo with the *develop* option, this avoids -reinstalling when there are changes in the code:: - - $ sudo python setup.py develop - -or using the "-e" option to pip:: - - $ pip install -e python-neo - -To update to the latest version from the repository:: - - $ git pull - - -Running the test suite ----------------------- - -Before you make any changes, run the test suite to make sure all the tests pass -on your system:: - - $ cd neo/test - -With Python 2.7 or 3.x:: - - $ python -m unittest discover - $ python3 -m unittest discover - -If you have nose installed:: - - $ nosetests - -At the end, if you see "OK", then all the tests -passed (or were skipped because certain dependencies are not installed), -otherwise it will report on tests that failed or produced errors. - -To run tests from an individual file:: - - $ python test_analogsignal.py - $ python3 test_analogsignal.py - - -Writing tests -------------- - -You should try to write automated tests for any new code that you add. If you -have found a bug and want to fix it, first write a test that isolates the bug -(and that therefore fails with the existing codebase). Then apply your fix and -check that the test now passes. - -To see how well the tests cover the code base, run:: - - $ nosetests --with-coverage --cover-package=neo --cover-erase - - -Working on the documentation ----------------------------- - -All modules, classes, functions, and methods (including private and subclassed -builtin methods) should have docstrings. -Please see `PEP257`_ for a description of docstring conventions. - -Module docstrings should explain briefly what functions or classes are present. -Detailed descriptions can be left for the docstrings of the respective -functions or classes. Private functions do not need to be explained here. - -Class docstrings should include an explanation of the purpose of the class -and, when applicable, how it relates to standard neuroscientific data. -They should also include at least one example, which should be written -so it can be run as-is from a clean newly-started Python interactive session -(that means all imports should be included). Finally, they should include -a list of all arguments, attributes, and properties, with explanations. -Properties that return data calculated from other data should explain what -calculation is done. A list of methods is not needed, since documentation -will be generated from the method docstrings. - -Method and function docstrings should include an explanation for what the -method or function does. If this may not be clear, one or more examples may -be included. Examples that are only a few lines do not need to include -imports or setup, but more complicated examples should have them. - -Examples can be tested easily using the iPython `%doctest_mode` magic. This will -strip >>> and ... from the beginning of each line of the example, so the -example can be copied and pasted as-is. - -The documentation is written in `reStructuredText`_, using the `Sphinx`_ -documentation system. Any mention of another Neo module, class, attribute, -method, or function should be properly marked up so automatic -links can be generated. The same goes for quantities or numpy. - -To build the documentation:: - - $ cd python-neo/doc - $ make html - -Then open `some/directory/python-neo/doc/build/html/index.html` in your browser. - -Committing your changes ------------------------ - -Once you are happy with your changes, **run the test suite again to check -that you have not introduced any new bugs**. It is also recommended to check -your code with a code checking program, such as `pyflakes`_ or `flake8`_. Then -you can commit them to your local repository:: - - $ git commit -m 'informative commit message' - -If this is your first commit to the project, please add your name and -affiliation/employer to :file:`doc/source/authors.rst` - -You can then push your changes to your online repository on GitHub:: - - $ git push - -Once you think your changes are ready to be included in the main Neo repository, -open a pull request on GitHub -(see https://help.github.com/articles/using-pull-requests). - - -Python version --------------- - -Neo core should work with both Python 2.7 and Python 3 (version 3.5 or newer). -Neo IO modules should ideally work with both Python 2 and 3, but certain -modules may only work with one or the other (see :doc:`install`). - -So far, we have managed to write code that works with both Python 2 and 3. -Mainly this involves avoiding the ``print`` statement (use ``logging.info`` -instead), and putting ``from __future__ import division`` at the beginning of -any file that uses division. - -If in doubt, `Porting to Python 3`_ by Lennart Regebro is an excellent resource. - -The most important thing to remember is to run tests with at least one version -of Python 2 and at least one version of Python 3. There is generally no problem -in having multiple versions of Python installed on your computer at once: e.g., -on Ubuntu Python 2 is available as `python` and Python 3 as `python3`, while -on Arch Linux Python 2 is `python2` and Python 3 `python`. See `PEP394`_ for -more on this. Using virtual environments makes this very straightforward. - - -Coding standards and style --------------------------- - -All code should conform as much as possible to `PEP 8`_, and should run with -Python 2.7, and 3.5 or newer. - -You can use the `pep8`_ program to check the code for PEP 8 conformity. -You can also use `flake8`_, which combines pep8 and pyflakes. - -However, the pep8 and flake8 programs do not check for all PEP 8 issues. -In particular, they do not check that the import statements are in the -correct order. - -Also, please do not use ``from xyz import *``. This is slow, can lead to -conflicts, and makes it difficult for code analysis software. - - -Making a release ----------------- - -.. TODO: discuss branching/tagging policy. - -Add a section in :file:`/doc/source/whatisnew.rst` for the release. - -First check that the version string (in :file:`neo/version.py`) is correct. - -To build a source package:: - - $ python setup.py sdist - - -Tag the release in the Git repository and push it:: - - $ git tag - $ git push --tags origin - $ git push --tags upstream - - -To upload the package to `PyPI`_ (currently Samuel Garcia, Andrew Davison, -Michael Denker and Julia Sprenger have the necessary permissions to do this):: - - $ twine upload dist/neo-0.X.Y.tar.gz - -.. talk about readthedocs - - - -.. make a release branch - - -If you want to develop your own IO module ------------------------------------------ - -See :ref:`io_dev_guide` for implementation of a new IO. - - - - -.. _Python: http://www.python.org -.. _nose: http://somethingaboutorange.com/mrl/projects/nose/ -.. _Setuptools: https://pypi.python.org/pypi/setuptools/ -.. _tox: http://codespeak.net/tox/ -.. _coverage: http://nedbatchelder.com/code/coverage/ -.. _`PEP 8`: http://www.python.org/dev/peps/pep-0008/ -.. _`issue tracker`: https://github.com/NeuralEnsemble/python-neo/issues -.. _`Porting to Python 3`: http://python3porting.com/ -.. _`NeuralEnsemble Google group`: http://groups.google.com/group/neuralensemble -.. _reStructuredText: http://docutils.sourceforge.net/rst.html -.. _Sphinx: http://sphinx.pocoo.org/ -.. _numpy: http://numpy.scipy.org/ -.. _quantities: http://pypi.python.org/pypi/quantities -.. _PEP257: http://www.python.org/dev/peps/pep-0257/ -.. _PEP394: http://www.python.org/dev/peps/pep-0394/ -.. _PyPI: http://pypi.python.org -.. _GitHub: http://github.com -.. _`GitHub Repository`: https://github.com/NeuralEnsemble/python-neo/ -.. _pep8: https://pypi.python.org/pypi/pep8 -.. _flake8: https://pypi.python.org/pypi/flake8/ -.. _pyflakes: https://pypi.python.org/pypi/pyflakes/ diff -Nru neo-0.10.0/doc/source/governance.rst neo-0.10.2/doc/source/governance.rst --- neo-0.10.0/doc/source/governance.rst 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/doc/source/governance.rst 2022-02-11 14:04:12.000000000 +0000 @@ -0,0 +1,34 @@ +========== +Governance +========== + +Neo is a community-developed project, +we welcome contributions from anyone who is interested in the project. +The project maintainers are the members of the `Neo maintainers team`_. +All contributors agree to abide by the Code of Conduct, see the file `CODE_OF_CONDUCT.md`_. + +Contributions +============= + +All contributions must be by pull request, +with the exception of quick bug fixes affecting fewer than ten lines of code. +Normally, pull requests may be approved and merged by any maintainer, +although anyone is welcome to join in the discussion. +In case of disagreement with a decision, we will try to reach a consensus between maintainers, +taking account of any input from the wider community. +If consensus cannot be reached, decisions will be based on a majority vote among the maintainers, +with the caveats that (i) only one vote per institution is allowed (i.e. in the case where several +maintainers belong to the same institution they will have to agree among themselves how to vote) +and (ii) a quorum of three maintainers must be achieved. + +Maintainers +=========== + +Any contributor who has had at least three pull requests accepted may be nominated as a maintainer. +Nominations must be approved by at least two existing maintainers, with no dissenting maintainer. +In case of disagreement, decisions on accepting new maintainers will be based on a majority vote +as above. Decisions on removing maintainers from the list are based on majority vote. + + +.. _`Neo maintainers team`: https://github.com/orgs/NeuralEnsemble/teams/neo-maintainers +.. _`CODE_OF_CONDUCT.md`: https://github.com/NeuralEnsemble/python-neo/blob/master/CODE_OF_CONDUCT.md \ No newline at end of file Binary files /tmp/tmpr40tq30c/hb2sCGn_pC/neo-0.10.0/doc/source/images/base_schematic.png and /tmp/tmpr40tq30c/WiNlIrMYeb/neo-0.10.2/doc/source/images/base_schematic.png differ Binary files /tmp/tmpr40tq30c/hb2sCGn_pC/neo-0.10.0/doc/source/images/.DS_Store and /tmp/tmpr40tq30c/WiNlIrMYeb/neo-0.10.2/doc/source/images/.DS_Store differ diff -Nru neo-0.10.0/doc/source/images/generate_io_overview.py neo-0.10.2/doc/source/images/generate_io_overview.py --- neo-0.10.0/doc/source/images/generate_io_overview.py 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/doc/source/images/generate_io_overview.py 2022-03-08 09:34:47.000000000 +0000 @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- + +""" +This generate diagram of the (raw)ios and formats + + +Author: Julia Sprenger +""" + +import pygraphviz +import neo + +# from datetime import datetime +# +# import numpy as np +# import quantities as pq +# from matplotlib import pyplot +# from matplotlib.patches import Rectangle, ArrowStyle, FancyArrowPatch +# from matplotlib.font_manager import FontProperties +# +# from neo.test.generate_datasets import fake_neo +# +# line_heigth = .22 +# fontsize = 10.5 +# left_text_shift = .1 +# dpi = 100 + + +default_style = {'shape': 'rectangle', + 'color': 'black', + 'fontcolor': 'black'} +IO_style = default_style.copy() +IO_style['fontsize'] = '30' +IO_style['penwidth'] = 6 + +styles = {'IO': {'ro': IO_style.copy(), + 'rw': IO_style.copy(), + 'raw': IO_style.copy() + }, + 'main': default_style.copy(), + 'ext': default_style.copy()} + +styles['IO']['ro']['color'] = '#20B2AA ' +styles['IO']['rw']['color'] = '#4169E1 ' +styles['IO']['raw']['color'] = '#008080 ' +styles['ext']['shape'] = 'circle' +styles['ext']['fillcolor'] = 'red' +styles['ext']['style'] = 'filled' + + +# styles['ext']['fixedsize'] = 'True' + + +def generate_diagram(filename, plot_extensions=False): + dia = pygraphviz.AGraph(strict=False, splines='true') + G = dia + G.node_attr['fontname'] = 'Arial' + # G.node_attr['shape'] = 'circle' + # G.node_attr['fixedsize'] = 'true' + # G.node_attr['sep'] = '-100' + G.node_attr['fixedsize'] = 'False' + # G.graph_attr['overlap'] = 'False' + G.graph_attr['packMode'] = 'clust' + # G.graph_attr['levelsgap'] = -500 + G.node_attr['fontsize'] = '20' + G.edge_attr['minlen'] = '0' + # G.node_attr['style'] = 'filled' + # G.graph_attr['outputorder'] = 'edgesfirst' + # G.graph_attr['splines'] = "compound" + G.graph_attr['label'] = "NEO {}".format(neo.__version__) + G.graph_attr['ratio'] = '1.0' + # G.edge_attr['color'] = '#1100FF' + + G.edge_attr['style'] = 'setlinewidth(4)' + + dia.add_node('NEO', shape='circle', fontsize=50) + + for io in neo.io.iolist: + io_name = io.name + rawio = False + if issubclass(io, neo.io.basefromrawio.BaseFromRaw): + rawio = True + if io_name == 'BaseIO': + io_name = io.__name__.rstrip('RawIO') + if io_name is None: + io_name = io.__name__.rstrip('IO') + if 'example' in io_name: + continue + + if io.is_writable and io.is_readable: + mode = 'rw' + elif io.is_readable: + mode = 'ro' + if rawio: + mode = 'raw' + + dia.add_node(io_name, **styles['IO'][mode]) + dia.add_edge('NEO', io_name) + + if plot_extensions: + for ext in io.extensions: + dia.add_node(ext, **styles['ext']) + dia.add_edge(io_name, ext, minlen=0) + + dia.layout(prog='fdp') # neato, dot, twopi, circo, fdp, nop, wc, acyclic, gvpr, gvcolor, + # ccomps, sccmap, tred, sfdp. + for ext in ['png', 'svg', 'eps']: + dia.draw('{}.{}'.format(filename, ext)) + + +if __name__ == '__main__': + generate_diagram('IODiagram', plot_extensions=False) + generate_diagram('IODiagram_ext', plot_extensions=True) + # pyplot.show() diff -Nru neo-0.10.0/doc/source/images/IODiagram.eps neo-0.10.2/doc/source/images/IODiagram.eps --- neo-0.10.0/doc/source/images/IODiagram.eps 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/doc/source/images/IODiagram.eps 2022-03-08 09:34:47.000000000 +0000 @@ -0,0 +1,1212 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: graphviz version 2.40.1 (20161225.0304) +%%Title: +%%Pages: 1 +%%BoundingBox: 36 36 1573 1573 +%%EndComments +save +%%BeginProlog +/DotDict 200 dict def +DotDict begin + +/setupLatin1 { +mark +/EncodingVector 256 array def + EncodingVector 0 + +ISOLatin1Encoding 0 255 getinterval putinterval +EncodingVector 45 /hyphen put + +% Set up ISO Latin 1 character encoding +/starnetISO { + dup dup findfont dup length dict begin + { 1 index /FID ne { def }{ pop pop } ifelse + } forall + /Encoding EncodingVector def + currentdict end definefont +} def +/Times-Roman starnetISO def +/Times-Italic starnetISO def +/Times-Bold starnetISO def +/Times-BoldItalic starnetISO def +/Helvetica starnetISO def +/Helvetica-Oblique starnetISO def +/Helvetica-Bold starnetISO def +/Helvetica-BoldOblique starnetISO def +/Courier starnetISO def +/Courier-Oblique starnetISO def +/Courier-Bold starnetISO def +/Courier-BoldOblique starnetISO def +cleartomark +} bind def + +%%BeginResource: procset graphviz 0 0 +/coord-font-family /Times-Roman def +/default-font-family /Times-Roman def +/coordfont coord-font-family findfont 8 scalefont def + +/InvScaleFactor 1.0 def +/set_scale { + dup 1 exch div /InvScaleFactor exch def + scale +} bind def + +% styles +/solid { [] 0 setdash } bind def +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def +/bold { 2 setlinewidth } bind def +/filled { } bind def +/unfilled { } bind def +/rounded { } bind def +/diagonals { } bind def +/tapered { } bind def + +% hooks for setting color +/nodecolor { sethsbcolor } bind def +/edgecolor { sethsbcolor } bind def +/graphcolor { sethsbcolor } bind def +/nopcolor {pop pop pop} bind def + +/beginpage { % i j npages + /npages exch def + /j exch def + /i exch def + /str 10 string def + npages 1 gt { + gsave + coordfont setfont + 0 0 moveto + (\() show i str cvs show (,) show j str cvs show (\)) show + grestore + } if +} bind def + +/set_font { + findfont exch + scalefont setfont +} def + +% draw text fitted to its expected width +/alignedtext { % width text + /text exch def + /width exch def + gsave + width 0 gt { + [] 0 setdash + text stringwidth pop width exch sub text length div 0 text ashow + } if + grestore +} def + +/boxprim { % xcorner ycorner xsize ysize + 4 2 roll + moveto + 2 copy + exch 0 rlineto + 0 exch rlineto + pop neg 0 rlineto + closepath +} bind def + +/ellipse_path { + /ry exch def + /rx exch def + /y exch def + /x exch def + matrix currentmatrix + newpath + x y translate + rx ry scale + 0 0 1 0 360 arc + setmatrix +} bind def + +/endpage { showpage } bind def +/showpage { } def + +/layercolorseq + [ % layer color sequence - darkest to lightest + [0 0 0] + [.2 .8 .8] + [.4 .8 .8] + [.6 .8 .8] + [.8 .8 .8] + ] +def + +/layerlen layercolorseq length def + +/setlayer {/maxlayer exch def /curlayer exch def + layercolorseq curlayer 1 sub layerlen mod get + aload pop sethsbcolor + /nodecolor {nopcolor} def + /edgecolor {nopcolor} def + /graphcolor {nopcolor} def +} bind def + +/onlayer { curlayer ne {invis} if } def + +/onlayers { + /myupper exch def + /mylower exch def + curlayer mylower lt + curlayer myupper gt + or + {invis} if +} def + +/curlayer 0 def + +%%EndResource +%%EndProlog +%%BeginSetup +14 default-font-family set_font +% /arrowlength 10 def +% /arrowwidth 5 def + +% make sure pdfmark is harmless for PS-interpreters other than Distiller +/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse +% make '<<' and '>>' safe on PS Level 1 devices +/languagelevel where {pop languagelevel}{1} ifelse +2 lt { + userdict (<<) cvn ([) cvn load put + userdict (>>) cvn ([) cvn load put +} if + +%%EndSetup +setupLatin1 +%%Page: 1 1 +%%PageBoundingBox: 36 36 1573 1573 +%%PageOrientation: Portrait +0 0 1 beginpage +gsave +36 36 1537 1537 boxprim clip newpath +1 1 set_scale 0 rotate 40 40 translate +0 0 0 graphcolor +14 /Times-Roman set_font +731.3023 3.8 moveto 67 (NEO 0.10.0) alignedtext +% NEO +gsave +1 setlinewidth +0 0 0 nodecolor +728.5955 758.11 88.5 88.5 ellipse_path stroke +0 0 0 nodecolor +50 /Arial set_font +674.0955 745.61 moveto 109 (NEO) alignedtext +grestore +% AlphaOmega +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 352.7627 600.03 moveto +161.7627 600.03 lineto +161.7627 559.03 lineto +352.7627 559.03 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +169.7627 572.03 moveto 175 (AlphaOmega) alignedtext +grestore +% NEO--AlphaOmega +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 652.5345 712.8639 moveto +603.2533 685.1746 536.8933 650.8706 474.7591 628.42 curveto +435.8123 614.3476 391.4265 603.4978 352.9522 595.6353 curveto +stroke +grestore +% AsciiImage IO +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 354.2934 1089.2 moveto +151.2934 1089.2 lineto +151.2934 1048.2 lineto +354.2934 1048.2 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +159.2934 1061.2 moveto 187 (AsciiImage IO) alignedtext +grestore +% NEO--AsciiImage IO +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 659.687 813.741 moveto +609.4897 853.2129 539.1346 906.396 473.8597 948.24 curveto +413.5139 986.9242 339.7605 1025.4811 294.5439 1048.1978 curveto +stroke +grestore +% AsciiSignal +gsave +6 setlinewidth +0.625 0.71111 0.88235 nodecolor +newpath 444.1588 1161.5 moveto +280.1588 1161.5 lineto +280.1588 1120.5 lineto +444.1588 1120.5 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +288.1588 1133.5 moveto 148 (AsciiSignal) alignedtext +grestore +% NEO--AsciiSignal +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 667.2622 822.1972 moveto +582.9133 910.3334 435.4885 1064.3777 382.1426 1120.1188 curveto +stroke +grestore +% AsciiSpikeTrain +gsave +6 setlinewidth +0.625 0.71111 0.88235 nodecolor +newpath 1030.7122 1147.2 moveto +807.7122 1147.2 lineto +807.7122 1106.2 lineto +1030.7122 1106.2 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +815.7122 1119.2 moveto 207 (AsciiSpikeTrain) alignedtext +grestore +% NEO--AsciiSpikeTrain +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 769.2538 836.7297 moveto +813.7551 922.7807 882.2652 1055.2565 908.4934 1105.9732 curveto +stroke +grestore +% AxographIO +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 1130.9214 186.15 moveto +954.9214 186.15 lineto +954.9214 145.15 lineto +1130.9214 145.15 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +962.9214 158.15 moveto 160 (AxographIO) alignedtext +grestore +% NEO--AxographIO +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 753.7016 673.1924 moveto +778.122 596.5498 819.0533 482.0474 870.6849 390.07 curveto +894.8463 347.0285 987.2454 233.2273 1025.8329 186.3151 curveto +stroke +grestore +% Axona IO +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 658.7173 95.789 moveto +517.7173 95.789 lineto +517.7173 54.789 lineto +658.7173 54.789 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +525.7173 67.789 moveto 125 (Axona IO) alignedtext +grestore +% NEO--Axona IO +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 687.6549 679.5073 moveto +646.6392 595.9789 586.2797 458.7624 562.4721 332.21 curveto +558.5773 311.5065 552.0531 303.1198 562.4721 284.81 curveto +573.2088 265.9418 593.7279 278.7282 604.4647 259.86 curveto +634.4535 207.1593 611.4701 131.9981 597.2651 96.0262 curveto +stroke +grestore +% Axon +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 601.2647 256.66 moveto +516.2647 256.66 lineto +516.2647 215.66 lineto +601.2647 215.66 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +524.2647 228.66 moveto 69 (Axon) alignedtext +grestore +% NEO--Axon +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 688.4492 678.9258 moveto +648.2398 595.2021 588.6758 458.0854 562.4721 332.21 curveto +557.1665 306.7235 556.9504 276.6316 557.5911 257.0113 curveto +stroke +grestore +% BCI2000 +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 439.7513 341.77 moveto +306.7513 341.77 lineto +306.7513 300.77 lineto +439.7513 300.77 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +314.7513 313.77 moveto 117 (BCI2000) alignedtext +grestore +% NEO--BCI2000 +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 681.5621 683.1014 moveto +639.23 617.8565 573.6258 522.1214 507.1485 446.14 curveto +472.2999 406.3092 426.1421 365.4686 398.1272 341.7804 curveto +stroke +grestore +% Blackrock IO for single nsx +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 1527.682 650.86 moveto +1157.682 650.86 lineto +1157.682 609.86 lineto +1527.682 609.86 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +1165.682 622.86 moveto 354 (Blackrock IO for single nsx) alignedtext +grestore +% NEO--Blackrock IO for single nsx +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 817.2658 752.3913 moveto +901.0665 745.6438 1029.8345 731.7896 1138.8255 705.12 curveto +1194.1162 691.5906 1255.106 668.0115 1295.8353 650.9453 curveto +stroke +grestore +% BLK IO +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 1080.6989 347.29 moveto +967.6989 347.29 lineto +967.6989 306.29 lineto +1080.6989 306.29 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +975.6989 319.29 moveto 97 (BLK IO) alignedtext +grestore +% NEO--BLK IO +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 778.7406 684.9424 moveto +847.9233 583.9968 968.7751 407.6598 1009.9725 347.548 curveto +stroke +grestore +% BrainVision +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 542.0459 168.26 moveto +374.0459 168.26 lineto +374.0459 127.26 lineto +542.0459 127.26 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +382.0459 140.26 moveto 152 (BrainVision) alignedtext +grestore +% NEO--BrainVision +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 696.5826 675.4633 moveto +648.8349 552.2989 564.0602 334.0709 559.6866 325.94 curveto +542.6598 294.286 531.4005 290.7741 513.0647 259.86 curveto +494.8164 229.0935 477.2354 191.4183 467.0422 168.5212 curveto +stroke +grestore +% Brainware DAM File +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 847.6721 329.01 moveto +565.6721 329.01 lineto +565.6721 288.01 lineto +847.6721 288.01 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +573.6721 301.01 moveto 266 (Brainware DAM File) alignedtext +grestore +% NEO--Brainware DAM File +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 724.2772 669.5519 moveto +719.0504 562.3619 710.5881 388.8177 707.6863 329.3088 curveto +stroke +grestore +% Brainware F32 File +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 784.1087 1161.5 moveto +518.1087 1161.5 lineto +518.1087 1120.5 lineto +784.1087 1120.5 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +526.1087 1133.5 moveto 250 (Brainware F32 File) alignedtext +grestore +% NEO--Brainware F32 File +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 711.0125 844.9937 moveto +692.7945 935.0155 665.5719 1069.532 655.2644 1120.465 curveto +stroke +grestore +% Brainware SRC File +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 279.9184 733.43 moveto +.9184 733.43 lineto +.9184 692.43 lineto +279.9184 692.43 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +8.9184 705.43 moveto 263 (Brainware SRC File) alignedtext +grestore +% NEO--Brainware SRC File +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 640.2212 751.3217 moveto +544.8937 743.9992 391.7919 732.2389 280.1302 723.6618 curveto +stroke +grestore +% Ced +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 1031.2428 1219.5 moveto +960.2428 1219.5 lineto +960.2428 1178.5 lineto +1031.2428 1178.5 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +968.2428 1191.5 moveto 55 (Ced) alignedtext +grestore +% NEO--Ced +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 799.5175 811.3729 moveto +874.1728 872.3351 987.2169 979.8053 1033.9122 1103 curveto +1041.3789 1122.6991 1040.7961 1130.4898 1033.9122 1150.4 curveto +1030.4065 1160.5397 1023.8154 1170.1735 1017.0843 1178.1495 curveto +stroke +grestore +% Elan +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 1063.3029 543.14 moveto +986.3029 543.14 lineto +986.3029 502.14 lineto +1063.3029 502.14 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +994.3029 515.14 moveto 61 (Elan) alignedtext +grestore +% NEO--Elan +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 798.043 702.9027 moveto +862.3375 651.7918 954.4926 578.5332 998.9135 543.2207 curveto +stroke +grestore +% igorpro +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 926.5337 1363.5 moveto +817.5337 1363.5 lineto +817.5337 1322.5 lineto +926.5337 1322.5 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +825.5337 1335.5 moveto 93 (igorpro) alignedtext +grestore +% NEO--igorpro +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 746.2666 845.1413 moveto +760.1505 917.6171 778.5543 1023.718 787.3087 1117.3 curveto +788.4619 1129.6277 786.1065 1216.9603 790.0413 1228.7 curveto +802.4587 1265.7486 831.3826 1301.1349 851.3294 1322.4647 curveto +stroke +grestore +% Intan +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 843.2339 243.46 moveto +760.2339 243.46 lineto +760.2339 202.46 lineto +843.2339 202.46 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +768.2339 215.46 moveto 67 (Intan) alignedtext +grestore +% NEO--Intan +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 759.9079 675.1695 moveto +790.1092 590.415 833.6951 454.2846 850.8721 332.21 curveto +853.8074 311.3488 857.8117 304.7009 850.8721 284.81 curveto +845.451 269.2715 834.3152 254.7103 824.0134 243.6243 curveto +stroke +grestore +% KlustaKwik +gsave +6 setlinewidth +0.625 0.71111 0.88235 nodecolor +newpath 925.6681 69.231 moveto +761.6681 69.231 lineto +761.6681 28.231 lineto +925.6681 28.231 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +769.6681 41.231 moveto 148 (KlustaKwik) alignedtext +grestore +% NEO--KlustaKwik +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 759.9079 675.1695 moveto +790.1092 590.415 833.6951 454.2846 850.8721 332.21 curveto +853.8074 311.3488 851.1934 305.8742 850.8721 284.81 curveto +849.6557 205.0645 846.1292 110.2196 844.505 69.252 curveto +stroke +grestore +% Kwik +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 597.6474 1233.9 moveto +517.6474 1233.9 lineto +517.6474 1192.9 lineto +597.6474 1192.9 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +525.6474 1205.9 moveto 64 (Kwik) alignedtext +grestore +% NEO--Kwik +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 672.238 826.7979 moveto +619.813 895.4922 545.3523 1006.5827 514.9087 1117.3 curveto +509.3233 1137.6128 507.4845 1144.9849 514.9087 1164.7 curveto +518.7937 1175.0168 525.9674 1184.5715 533.3426 1192.4358 curveto +stroke +grestore +% MEArec +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 1135.6255 701.92 moveto +1012.6255 701.92 lineto +1012.6255 660.92 lineto +1135.6255 660.92 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +1020.6255 673.92 moveto 107 (MEArec) alignedtext +grestore +% NEO--MEArec +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 815.3413 738.8569 moveto +876.7129 725.2355 957.5276 707.2988 1012.4038 695.1191 curveto +stroke +grestore +% Maxwell +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 1179.204 905.96 moveto +1054.204 905.96 lineto +1054.204 864.96 lineto +1179.204 864.96 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +1062.204 877.96 moveto 109 (Maxwell) alignedtext +grestore +% NEO--Maxwell +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 812.8092 785.7431 moveto +885.3766 809.5546 988.5002 843.3925 1053.9989 864.8846 curveto +stroke +grestore +% Micromed +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 724.5785 1469.4 moveto +577.5785 1469.4 lineto +577.5785 1428.4 lineto +724.5785 1428.4 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +585.5785 1441.4 moveto 131 (Micromed) alignedtext +grestore +% NEO--Micromed +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 761.0957 840.6734 moveto +789.1259 923.9483 820.3114 1055.4634 787.3087 1164.7 curveto +761.2835 1250.8413 709.9326 1250.2862 675.2004 1333.3 curveto +661.9856 1364.8848 655.7468 1404.4552 653.0062 1428.1514 curveto +stroke +grestore +% NIX +gsave +6 setlinewidth +0.625 0.71111 0.88235 nodecolor +newpath 940.8849 434.27 moveto +873.8849 434.27 lineto +873.8849 393.27 lineto +940.8849 393.27 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +881.8849 406.27 moveto 51 (NIX) alignedtext +grestore +% NEO--NIX +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 769.3893 679.5431 moveto +810.7173 599.9473 871.9563 482.0037 896.5668 434.6052 curveto +stroke +grestore +% neomatlab +gsave +6 setlinewidth +0.625 0.71111 0.88235 nodecolor +newpath 1271.107 774.29 moveto +1116.107 774.29 lineto +1116.107 733.29 lineto +1271.107 733.29 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +1124.107 746.29 moveto 139 (neomatlab) alignedtext +grestore +% NEO--neomatlab +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 817.1551 757.2873 moveto +903.4558 756.4855 1033.3776 755.2785 1115.8062 754.5128 curveto +stroke +grestore +% nest +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 470.6597 945.04 moveto +397.6597 945.04 lineto +397.6597 904.04 lineto +470.6597 904.04 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +405.6597 917.04 moveto 57 (nest) alignedtext +grestore +% NEO--nest +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 651.2359 801.8375 moveto +592.9649 834.7753 515.6847 878.4579 470.79 903.8347 curveto +stroke +grestore +% Neuralynx +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 1227.3337 543.02 moveto +1076.3337 543.02 lineto +1076.3337 502.02 lineto +1227.3337 502.02 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +1084.3337 515.02 moveto 135 (Neuralynx) alignedtext +grestore +% NEO--Neuralynx +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 806.2239 714.8992 moveto +897.7436 663.956 1046.0621 581.3964 1114.7463 543.1643 curveto +stroke +grestore +% NeuroExplorer +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 1354.7776 978.31 moveto +1145.7776 978.31 lineto +1145.7776 937.31 lineto +1354.7776 937.31 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +1153.7776 950.31 moveto 193 (NeuroExplorer) alignedtext +grestore +% NEO--NeuroExplorer +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 806.5815 800.0123 moveto +870.764 833.1758 964.8678 878.8073 1051.004 909.16 curveto +1082.4086 920.2264 1117.4555 929.6989 1149.2948 937.2655 curveto +stroke +grestore +% NeuroScope +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 357.0501 945.99 moveto +175.0501 945.99 lineto +175.0501 904.99 lineto +357.0501 904.99 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +183.0501 917.99 moveto 166 (NeuroScope) alignedtext +grestore +% NEO--NeuroScope +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 645.3674 788.2275 moveto +552.1226 821.9697 403.4878 875.7558 322.746 904.9736 curveto +stroke +grestore +% neuroshare +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 380.1704 805.8 moveto +213.1704 805.8 lineto +213.1704 764.8 lineto +380.1704 764.8 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +221.1704 777.8 moveto 151 (neuroshare) alignedtext +grestore +% NEO--neuroshare +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 640.1467 763.6779 moveto +564.0067 768.471 454.9211 775.338 380.2349 780.0396 curveto +stroke +grestore +% NeoNWB IO +gsave +6 setlinewidth +0.625 0.71111 0.88235 nodecolor +newpath 471.5591 672.62 moveto +289.5591 672.62 lineto +289.5591 631.62 lineto +471.5591 631.62 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +297.5591 644.62 moveto 166 (NeoNWB IO) alignedtext +grestore +% NEO--NeoNWB IO +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 643.9013 732.3175 moveto +583.7394 713.9959 504.0351 689.723 448.1308 672.6981 curveto +stroke +grestore +% OpenEphys +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 351.7952 442.65 moveto +178.7952 442.65 lineto +178.7952 401.65 lineto +351.7952 401.65 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +186.7952 414.65 moveto 157 (OpenEphys) alignedtext +grestore +% NEO--OpenEphys +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 655.878 707.4506 moveto +580.6807 654.7799 460.1456 569.558 357.7485 493.54 curveto +335.1156 476.7377 309.804 457.1348 291.3951 442.7261 curveto +stroke +grestore +% OpenEphysBinary +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 1192.8616 1426 moveto +935.8616 1426 lineto +935.8616 1385 lineto +1192.8616 1385 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +943.8616 1398 moveto 241 (OpenEphysBinary) alignedtext +grestore +% NEO--OpenEphysBinary +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 799.0474 811.9658 moveto +873.0045 873.249 985.1737 980.8144 1033.9122 1103 curveto +1037.4794 1111.9427 1036.1258 1180.0032 1036.9 1189.6 curveto +1042.7035 1261.5349 1055.1337 1346.3115 1061.0719 1384.7245 curveto +stroke +grestore +% Phy IO +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 508.9356 1234 moveto +400.9356 1234 lineto +400.9356 1193 lineto +508.9356 1193 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +408.9356 1206 moveto 92 (Phy IO) alignedtext +grestore +% NEO--Phy IO +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 682.945 834.0757 moveto +618.6189 941.119 504.9515 1130.2698 467.378 1192.7948 curveto +stroke +grestore +% Python pickle file +gsave +6 setlinewidth +0.625 0.71111 0.88235 nodecolor +newpath 1330.9169 382.41 moveto +1089.9169 382.41 lineto +1089.9169 341.41 lineto +1330.9169 341.41 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +1097.9169 354.41 moveto 225 (Python pickle file) alignedtext +grestore +% NEO--Python pickle file +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 786.1678 690.6511 moveto +835.2449 635.4198 909.3642 557.178 983.1029 498.94 curveto +1043.6743 451.1014 1122.2965 407.2009 1169.4174 382.5651 curveto +stroke +grestore +% Plexon +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 556.4866 370.14 moveto +448.4866 370.14 lineto +448.4866 329.14 lineto +556.4866 329.14 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +456.4866 342.14 moveto 92 (Plexon) alignedtext +grestore +% NEO--Plexon +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 685.5339 680.3185 moveto +632.3593 584.2574 545.1261 426.6691 513.9815 370.4058 curveto +stroke +grestore +% RawBinarySignal +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 478.6193 1375.3 moveto +233.6193 1375.3 lineto +233.6193 1334.3 lineto +478.6193 1334.3 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +241.6193 1347.3 moveto 229 (RawBinarySignal) alignedtext +grestore +% NEO--RawBinarySignal +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 689.2196 837.6163 moveto +641.9054 926.6174 555.2426 1070.6542 447.3588 1164.7 curveto +428.7283 1180.9408 413.1762 1170.5011 397.7356 1189.8 curveto +363.4066 1232.707 356.993 1300.3671 356.0522 1334.1607 curveto +stroke +grestore +% RawMCS +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 503.9485 490.34 moveto +360.9485 490.34 lineto +360.9485 449.34 lineto +503.9485 449.34 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +368.9485 462.34 moveto 127 (RawMCS) alignedtext +grestore +% NEO--RawMCS +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 665.0645 696.2689 moveto +598.4416 631.418 497.4798 533.1416 453.8136 490.6369 curveto +stroke +grestore +% Spike2 +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 786.4004 1377.5 moveto +678.4004 1377.5 lineto +678.4004 1336.5 lineto +786.4004 1336.5 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +686.4004 1349.5 moveto 92 (Spike2) alignedtext +grestore +% NEO--Spike2 +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 754.8987 842.9616 moveto +777.0674 925.1932 802.8798 1053.4543 787.3087 1164.7 curveto +778.3328 1228.8271 753.2933 1301.5794 740.3592 1336.3552 curveto +stroke +grestore +% SpikeGadgets +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 937.8168 1528.9 moveto +733.8168 1528.9 lineto +733.8168 1487.9 lineto +937.8168 1487.9 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +741.8168 1500.9 moveto 188 (SpikeGadgets) alignedtext +grestore +% NEO--SpikeGadgets +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 746.2666 845.1413 moveto +760.1505 917.6171 778.5543 1023.718 787.3087 1117.3 curveto +791.9216 1166.6107 785.4236 1179.3897 790.0413 1228.7 curveto +799.1938 1326.4364 821.8809 1441.7043 831.4493 1487.8235 curveto +stroke +grestore +% SpikeGLX +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 1192.1 1186.4 moveto +1040.1 1186.4 lineto +1040.1 1145.4 lineto +1192.1 1145.4 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +1048.1 1158.4 moveto 136 (SpikeGLX) alignedtext +grestore +% NEO--SpikeGLX +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 789.5694 822.2758 moveto +878.8742 916.2556 1040.6936 1086.5462 1096.5332 1145.3088 curveto +stroke +grestore +% Stimfit +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 956.9219 258.6 moveto +856.9219 258.6 lineto +856.9219 217.6 lineto +956.9219 217.6 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +864.9219 230.6 moveto 84 (Stimfit) alignedtext +grestore +% NEO--Stimfit +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 757.3457 674.2726 moveto +799.6086 551.0317 876.0597 328.0959 899.7359 259.0547 curveto +stroke +grestore +% Tdt +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 852.2413 1225.5 moveto +793.2413 1225.5 lineto +793.2413 1184.5 lineto +852.2413 1184.5 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +801.2413 1197.5 moveto 43 (Tdt) alignedtext +grestore +% NEO--Tdt +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 742.1661 845.7137 moveto +755.3554 925.7062 777.346 1046.9035 804.5122 1150.4 curveto +807.5061 1161.806 811.613 1174.2976 815.1708 1184.4506 curveto +stroke +grestore +% TIFF IO +gsave +6 setlinewidth +0.49087 0.82022 0.69804 nodecolor +newpath 1136.6452 1043.8 moveto +1017.6452 1043.8 lineto +1017.6452 1002.8 lineto +1136.6452 1002.8 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +1025.6452 1015.8 moveto 103 (TIFF IO) alignedtext +grestore +% NEO--TIFF IO +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 799.1297 811.7752 moveto +876.5098 870.6489 996.7912 962.1635 1050.1168 1002.7357 curveto +stroke +grestore +% WinEdr +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 782.6328 141.68 moveto +667.6328 141.68 lineto +667.6328 100.68 lineto +782.6328 100.68 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +675.6328 113.68 moveto 99 (WinEdr) alignedtext +grestore +% NEO--WinEdr +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 759.9079 675.1695 moveto +790.1092 590.415 833.6951 454.2846 850.8721 332.21 curveto +853.8074 311.3488 851.418 305.8696 850.8721 284.81 curveto +850.3788 265.7797 855.9811 215.7295 846.4339 199.26 curveto +831.2986 173.1507 803.5361 154.3213 778.3872 141.7034 curveto +stroke +grestore +% WinWcp +gsave +6 setlinewidth +0.5 1 0.50196 nodecolor +newpath 615.8696 1395.2 moveto +487.8696 1395.2 lineto +487.8696 1354.2 lineto +615.8696 1354.2 lineto +closepath stroke +0 0 0 nodecolor +30 /Arial set_font +495.8696 1367.2 moveto 112 (WinWcp) alignedtext +grestore +% NEO--WinWcp +gsave +4 setlinewidth +0 0 0 edgecolor +newpath 672.3922 826.8406 moveto +620.0823 895.5667 545.7048 1006.6803 514.9087 1117.3 curveto +511.3386 1130.1235 512.6852 1223.9059 514.4474 1237.1 curveto +520.1171 1279.552 535.2138 1327.4667 544.4071 1354.0739 curveto +stroke +grestore +endpage +showpage +grestore +%%PageTrailer +%%EndPage: 1 +%%Trailer +end +restore +%%EOF Binary files /tmp/tmpr40tq30c/hb2sCGn_pC/neo-0.10.0/doc/source/images/IODiagram.png and /tmp/tmpr40tq30c/WiNlIrMYeb/neo-0.10.2/doc/source/images/IODiagram.png differ diff -Nru neo-0.10.0/doc/source/images/neo_ecosystem.drawio neo-0.10.2/doc/source/images/neo_ecosystem.drawio --- neo-0.10.0/doc/source/images/neo_ecosystem.drawio 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/doc/source/images/neo_ecosystem.drawio 2022-03-08 09:34:47.000000000 +0000 @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/tmpr40tq30c/hb2sCGn_pC/neo-0.10.0/doc/source/images/neo_ecosystem.png and /tmp/tmpr40tq30c/WiNlIrMYeb/neo-0.10.2/doc/source/images/neo_ecosystem.png differ Binary files /tmp/tmpr40tq30c/hb2sCGn_pC/neo-0.10.0/doc/source/images/neologo_optical.png and /tmp/tmpr40tq30c/WiNlIrMYeb/neo-0.10.2/doc/source/images/neologo_optical.png differ Binary files /tmp/tmpr40tq30c/hb2sCGn_pC/neo-0.10.0/doc/source/images/neo_UML_French_workshop.png and /tmp/tmpr40tq30c/WiNlIrMYeb/neo-0.10.2/doc/source/images/neo_UML_French_workshop.png differ diff -Nru neo-0.10.0/doc/source/releases/0.10.0.rst.orig neo-0.10.2/doc/source/releases/0.10.0.rst.orig --- neo-0.10.0/doc/source/releases/0.10.0.rst.orig 2021-07-26 15:40:28.000000000 +0000 +++ neo-0.10.2/doc/source/releases/0.10.0.rst.orig 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -======================== -Neo 0.10.0 release notes -======================== - -26th July 2021 - -.. currentmodule:: neo.core - -Removal of Unit and ChannelIndex --------------------------------- -In version 0.9.0 :class:`Group` and :class:`ChannelView` were introduced, replacing :class:`Unit` and :class:`ChannelIndex`, which were deprecated. -In this version the deprecated :class:`Unit` and :class:`ChannelIndex` are removed and only the new :class:`Group` and :class:`ChannelView` objects are available. - -Supported Python and NumPy versions ------------------------------------ - -We no longer support Python 3.6, nor versions of NumPy older than 1.16. - -Other new or modified features ------------------------------- - -* Lists of :class:`SpikeTrain` objects can now also be created from two arrays: one containing spike times - and the other unit identities of the times (:class:`SpikeTrainList`). -* Object identity is now preserved when using utility :func:`time_slice()` methods. - -See all `pull requests`_ included in this release and the `list of closed issues`_. - - -New IO modules --------------- - -<<<<<<< Updated upstream - * CEDIO - an alternative to spike2io - * AxonaIO - * OpenEphysIO - handle the binary format - * PhyIO - * SpikeGLXIO - * NWBIO - * MaxwellIO - -RawIO modules -------------- - -Internal refactoring of the neo.rawio module about the channel grouping. -There is a signal_stream filed that handle channel groups for signal. -This enhanced the way annotation and array_annotaion are rendered at neo.io level. - -======= -.. currentmodule:: neo.io - -* :class:`CEDIO` - an alternative to :class:`Spike2IO` -* :class:`AxonaIO` -* :class:`OpenEphysIO` -* :class:`PhyIO` -* :class:`SpikeGLXIO` -* :class:`NWBIO` - support for a subset of the `NWB:N`_ format ->>>>>>> Stashed changes - -Bug fixes and improvements in IO modules ----------------------------------------- - -* :class:`NeuralynxIO` was refactored and now supports new file versions (neuraview) and single file loading. -* Legacy versions of old IOs were removed for NeuralynxIO (neuralynxio_v1), BlackrockIO, NeoHdf5IO. -* :class:`NixIOfr` now supports array annotations of :class:`AnalogSignal` objects. -* The IO modules of this release have been tested with version 0.1.0 of the `ephy_testing_data`_. -* :class:`NSDFIO` was removed. -* all IOs now accept :class:`pathlib.Path` objects. - - -Acknowledgements ----------------- - -Thanks to Samuel Garcia, Julia Sprenger, Peter N. Steinmetz, Andrew Davison, Steffen Bürgers, -Regimantas Jurkus, Alessio Buccino, Shashwat Sridhar, Jeffrey Gill, Etienne Combrisson, -Ben Dichter and Elodie Legouée for their contributions to this release. - -.. _`list of closed issues`: https://github.com/NeuralEnsemble/python-neo/issues?q=is%3Aissue+milestone%3A0.10.0+is%3Aclosed -.. _`pull requests`: https://github.com/NeuralEnsemble/python-neo/pulls?q=is%3Apr+is%3Aclosed+merged%3A%3E2020-11-10+milestone%3A0.10.0 -<<<<<<< Updated upstream -.. _`ephy_test_data`: https://gin.g-node.org/NeuralEnsemble/ephy_testing_data/src/v0.1.0 -======= -.. _`ephy_testing_data`: https://gin.g-node.org/NeuralEnsemble/ephy_testing_data/src/v0.1.0 -.. _`NWB:N`: https://www.nwb.org/nwb-neurophysiology/ ->>>>>>> Stashed changes diff -Nru neo-0.10.0/doc/source/releases/0.10.1.rst neo-0.10.2/doc/source/releases/0.10.1.rst --- neo-0.10.0/doc/source/releases/0.10.1.rst 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/doc/source/releases/0.10.1.rst 2022-03-08 09:34:55.000000000 +0000 @@ -0,0 +1,33 @@ +======================== +Neo 0.10.1 release notes +======================== + +2nd March 2022 + + +Bug fixes and improvements in IO modules +---------------------------------------- + +* :class:`NeuralynxIO` memory performace was improved during initialization [#998](https://github.com/NeuralEnsemble/python-neo/pull/990) and new arguments for file selection were added [#1023](https://github.com/NeuralEnsemble/python-neo/pull/1023) [#1043](https://github.com/NeuralEnsemble/python-neo/pull/1043) +* :class:`TdtIO` can load single block tdt datasets [#1057](https://github.com/NeuralEnsemble/python-neo/pull/1057) +* :class:`SpikeGLXIO` supports neuropixel 2.0 format [#1045](https://github.com/NeuralEnsemble/python-neo/pull/1045) and uses corrected gain values [#1069](https://github.com/NeuralEnsemble/python-neo/pull/1069) +* :class:`NixIO` some bug fix related to nixio module +* :class:`NwbIO` various improvement [#1052](https://github.com/NeuralEnsemble/python-neo/pull/1052) [#1054](https://github.com/NeuralEnsemble/python-neo/pull/1054) +* :class:`OpenEphysIO` small bug fix [#1062](https://github.com/NeuralEnsemble/python-neo/pull/1062) +* :class:`MaxwellIO` bug fix [#1074](https://github.com/NeuralEnsemble/python-neo/pull/1074) +* :class:`NeuroscopeIO` bug fix [#1078](https://github.com/NeuralEnsemble/python-neo/pull/1078) +* The IO modules of this release have been tested with version 0.1.1 of the `ephy_testing_data`_. + +Documentation +------------- +A project governance guide has been added [#1048](https://github.com/NeuralEnsemble/python-neo/pull/1048) + + +Acknowledgements +---------------- + +Thanks to Samuel Garcia, Julia Sprenger, Andrew Davison, Alessio Buccino, Ben Dichter, +Elodie Legouée, Eric Larson and Heberto Mayorquin for their contributions to this release. + +.. _`ephy_testing_data`: https://gin.g-node.org/NeuralEnsemble/ephy_testing_data/src/v0.1.1 + diff -Nru neo-0.10.0/doc/source/releases/0.10.2.rst neo-0.10.2/doc/source/releases/0.10.2.rst --- neo-0.10.0/doc/source/releases/0.10.2.rst 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/doc/source/releases/0.10.2.rst 2022-03-08 14:27:41.000000000 +0000 @@ -0,0 +1,10 @@ +======================== +Neo 0.10.2 release notes +======================== + +8th March 2022 + +This release fixes the following bugs introduced in 0.10.1: + +1. Remove broken imports in `spike2rawio.py `_ +2. Fix the compilation of the documentation on `readthedoc `_ diff -Nru neo-0.10.0/doc/source/releases/0.8.0.rst.orig neo-0.10.2/doc/source/releases/0.8.0.rst.orig --- neo-0.10.0/doc/source/releases/0.8.0.rst.orig 2019-09-26 12:35:09.000000000 +0000 +++ neo-0.10.2/doc/source/releases/0.8.0.rst.orig 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -======================= -Neo 0.8.0 release notes -======================= - -27th September 2019 - -Neo 0.8 sees a major new feature, the ability to selectively load only parts of a data file -(for supported file formats) into memory, for example only a subset of the signals -in a segment, a subset of the channels in a signal, or even only a certain time slice of a given signal. - -This can lead to major savings in time and memory consumption, or can allow files that are too -large to be loaded into memory in their entirety to be processed one section at a time. - -Here is an example, loading only certain sections of a signal:: - - lim0, lim1 = -500*pq.ms, +1500*pq.ms - seg = reader.read_segment(lazy=True) # this loads only the segment structure and metadata - # but all data objects are replaced by proxies - triggers = seg.events[0].load() # this loads all triggers in memory - sigproxy = seg.analogsignals[0] # this is a proxy object - all_sig_chunks = [] - for t in triggers.times: - t0, t1 = (t + lim0), (t + lim1) - sig_chunk = sigproxy.load(time_slice=(t0, t1)) # here the actual data are loaded - all_sig_chunks.append(sig_chunk) - -Not all IO modules support lazy loading (but many do). To know whether a given IO class supports lazy mode, -use ``SomeIO.support_lazy``. - -For more details, see :ref:`section-lazy`. - -Other new features ------------------- - - * new neo.utils module -<<<<<<< Updated upstream - * Numpy 1.16+ compatibility - * :meth:`time_shift()` method for :class:`Epoch`/:class:`Event`/:class:`AnalogSignal` - * :meth:`time_slice()` method is now more robust - -See all `pull requests`_ included in this release and the `list of closed issues`_. - -Bug fixes and improvements in IO modules ----------------------------------------- - -======= - -Other features: - * Event and Epoch do not use array_annotations machinery - * deep copy annotations when slicing - * numpy 1.16 compatibility - * time_shift() method for Epoch/Event/AnalogSignal - * time_slice more robust - -Many bug fixes and improvements in IO: ->>>>>>> Stashed changes - * Blackrock - * Neuroshare - * NixIOFr - * NixIO (array annotation + 1d coordinates) - * AsciiSignal (fix + json metadata + IrregularlySampledSignals + write proxy) - * Spike2 (group same sampling rate) - * Brainvision - * NeuralynxIO - -<<<<<<< Updated upstream -.. Warning:: Some IOs (based on rawio) when loading can choose to split each - channel into its own 1-channel :class:`AnalogSignal` or to group them - in a multi-channel :class:`AnalogSignal`. - The default behavior (either ``signal_group_mode='split-all'`` - or ``'group-same-units'``) is not the same for all IOs for backwards - compatibility reasons. In the next release, all IOs will have the default - ``signal_group_mode='group-same-units'`` - -Acknowledgements ----------------- - -Thanks to Achileas Koutsou, Chek Yin Choi, Richard C. Gerkin, -Alexander Kleinjohann, Björn Müller, Jeffrey Gill, Christian Kothe, -Mike Sintsov, @rishidhingra, Michael Denker, Julia Sprenger, -======= -Warning: - * Some IOs (base on rawio) when loading can choose to split each - channel into separted AnalogSignal or to group then. - The default behavior (either signal_group_mode='split-all' - or 'group-same-units') was not the same for all IOs for retro - compatibility reasons. In next release, all IOs will be - signal_group_mode='group-same-units' - * last release supporting python2.7 - -See all `Github pull requests`_ included in this release and the `list of closed issues`_. - -Thanks to Achileas Koutsou, Chek Yin Choi, Richard C Gerkin, -Alexander Kleinjohann, Björn Müller, Jeffrey Gill, Christian Kothe, -Mike Sintsov, rishidhingra, Michael Denker, Julia Sprenger, Corentin Fragnaud, ->>>>>>> Stashed changes -Andrew Davison and Samuel Garcia for their contributions to this release. - -.. Warning:: This may be the last release supporting Python 2.7. - In any case, Python 2.7 support will be dropped before Neo 1.0. - - -<<<<<<< Updated upstream -.. _`list of closed issues`: https://github.com/NeuralEnsemble/python-neo/issues?q=is%3Aissue+milestone%3A0.7.0+is%3Aclosed -.. _`pull requests`: https://github.com/NeuralEnsemble/python-neo/pulls?q=is%3Apr+is%3Aclosed+merged%3A%3E2018-11-27+milestone%3A0.8.0 -======= -.. _`list of closed issues`: https://github.com/NeuralEnsemble/python-neo/issues?q=is%3Aissue+milestone%3A0.8.0+is%3Aclosed -.. _`Github pull requests`: https://github.com/NeuralEnsemble/python-neo/pulls?q=is%3Apr+is%3Aclosed+merged%3A%3E2018-11-27+milestone%3A0.8.0 ->>>>>>> Stashed changes diff -Nru neo-0.10.0/doc/source/whatisnew.rst neo-0.10.2/doc/source/whatisnew.rst --- neo-0.10.0/doc/source/whatisnew.rst 2021-07-27 08:39:25.000000000 +0000 +++ neo-0.10.2/doc/source/whatisnew.rst 2022-03-08 14:27:41.000000000 +0000 @@ -6,6 +6,8 @@ .. toctree:: :maxdepth: 1 + releases/0.10.2.rst + releases/0.10.1.rst releases/0.10.0.rst releases/0.9.0.rst releases/0.8.0.rst diff -Nru neo-0.10.0/examples/hbp_d571_example2.py neo-0.10.2/examples/hbp_d571_example2.py --- neo-0.10.0/examples/hbp_d571_example2.py 2020-12-08 08:02:22.000000000 +0000 +++ neo-0.10.2/examples/hbp_d571_example2.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -import os -import matplotlib.pyplot as plt -import numpy as np -from quantities import Hz, mm, dimensionless -from neo.core import CircularRegionOfInterest -from neo.io import TiffIO -import elephant as el - -data_path = os.path.expanduser("~/Data/WaveScalES/LENS/170110_mouse2_deep/t1") - -# loading data -data = TiffIO( - data_path, units=dimensionless, sampling_rate=25 * Hz, spatial_scale=0.05 * mm -).read() -# data = TiffIO(data_path).read(units=dimensionless, sampling_rate=25 * Hz, spatial_scale=0.05 * mm) -images = data[0].segments[0].imagesequences[0] -images /= images.max() -plt.subplot(2, 2, 1) -plt.imshow(images[100], cmap="gray") -plt.title("Original image (frame 100)") -print(images.min(), images.max(), images.mean()) ### -# preprocessing -background = np.mean(images, axis=0) -print(background.min(), background.max(), background.mean()) -preprocessed_images = images - background -print( - preprocessed_images.min(), - preprocessed_images.max(), - preprocessed_images.mean(), - preprocessed_images.shape, - preprocessed_images.dtype, -) -np.save("preprocessed_images_orig.npy", preprocessed_images.magnitude) -plt.subplot(2, 2, 2) -plt.imshow(preprocessed_images[100], cmap="gray") -plt.title("Subtracted background (frame 100)") - -# defining ROI and extracting signal -roi = CircularRegionOfInterest(x=50, y=50, radius=10) -circle = plt.Circle(roi.centre, roi.radius, color="b", fill=False) -ax = plt.gca() -ax.add_artist(circle) - -central_signal = preprocessed_images.signal_from_region(roi)[0] -plt.subplot(2, 2, 3) -plt.plot(central_signal.times, central_signal, lw=0.8) -plt.title("Mean signal from ROI") -plt.xlabel("Time [s]") - -# calculating power spectrum -freqs, psd = el.spectral.welch_psd( - central_signal, fs=central_signal.sampling_rate, freq_res=0.1 * Hz, overlap=0.8 -) -plt.subplot(2, 2, 4) -plt.plot(freqs, np.mean(psd, axis=0), lw=0.8) -plt.title("Average power spectrum") -plt.xlabel("frequency [Hz]") -plt.ylabel("Fourier signal") - -plt.tight_layout() -plt.show() # see Figure 2 diff -Nru neo-0.10.0/examples/hbp_d571_example_orig.py neo-0.10.2/examples/hbp_d571_example_orig.py --- neo-0.10.0/examples/hbp_d571_example_orig.py 2020-12-08 08:02:22.000000000 +0000 +++ neo-0.10.2/examples/hbp_d571_example_orig.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -import os -import matplotlib.pyplot as plt -import numpy as np -from quantities import Hz, mm, dimensionless -from neo.core import CircularRegionOfInterest -from neo.io import TiffIO -import elephant as el - -data_path = os.path.expanduser("~/Data/WaveScalES/LENS/170110_mouse2_deep/t1") - -# loading data -data = TiffIO(data_path).read(units=dimensionless, sampling_rate=25 * Hz, spatial_scale=0.05 * mm) -images = data[0].segments[0].imagesequences[0] -images /= images.max() -plt.subplot(2, 2, 1) -plt.imshow(images[100], cmap="gray") -plt.title("Original image (frame 100)") - -# preprocessing -background = np.mean(images, axis=0) -preprocessed_images = images - background -plt.subplot(2, 2, 2) -plt.imshow(preprocessed_images[100], cmap="gray") -plt.title("Subtracted background (frame 100)") - -# defining ROI and extracting signal -roi = CircularRegionOfInterest(x=50, y=50, radius=10) -circle = plt.Circle(roi.centre, roi.radius, color="b", fill=False) -ax = plt.gca() -ax.add_artist(circle) - -central_signal = preprocessed_images.signal_from_region(roi)[0] -plt.subplot(2, 2, 3) -plt.plot(central_signal.times, central_signal, lw=0.8) -plt.title("Mean signal from ROI") -plt.xlabel("Time [s]") - -# calculating power spectrum -freqs, psd = el.spectral.welch_psd( - central_signal, fs=central_signal.sampling_rate, freq_res=0.1 * Hz, overlap=0.8 -) -plt.subplot(2, 2, 4) -plt.plot(freqs, np.mean(psd, axis=0), lw=0.8) -plt.title("Average power spectrum") -plt.xlabel("frequency [Hz]") -plt.ylabel("Fourier signal") - -plt.tight_layout() -plt.show() # see Figure 2 diff -Nru neo-0.10.0/examples/hbp_d571_example.py neo-0.10.2/examples/hbp_d571_example.py --- neo-0.10.0/examples/hbp_d571_example.py 2020-12-08 08:02:22.000000000 +0000 +++ neo-0.10.2/examples/hbp_d571_example.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -import os -import matplotlib.pyplot as plt -import numpy as np -from quantities import Hz, mm, dimensionless -from neo.core import CircularRegionOfInterest -from neo.io import TiffIO -import elephant as el - -data_path = os.path.expanduser("~/Data/WaveScalES/LENS/170110_mouse2_deep/t1") - -# loading data -data = TiffIO( - data_path, units=dimensionless, sampling_rate=25 * Hz, spatial_scale=0.05 * mm -).read() -images = data[0].segments[0].imagesequences[0] -images /= images.max() -plt.subplot(2, 2, 1) -plt.imshow(images[100], cmap="gray") -plt.title("Original image (frame 100)") - -# preprocessing -background = np.mean(images, axis=0) -preprocessed_images = images - background -plt.subplot(2, 2, 2) -plt.imshow(preprocessed_images[100], cmap="gray") -plt.title("Subtracted background (frame 100)") - -# defining ROI and extracting signal -roi = CircularRegionOfInterest(x=50, y=50, radius=10) -circle = plt.Circle(roi.centre, roi.radius, color="b", fill=False) -ax = plt.gca() -ax.add_artist(circle) - -central_signal = preprocessed_images.signal_from_region(roi)[0] -plt.subplot(2, 2, 3) -plt.plot(central_signal.times, central_signal, lw=0.8) -plt.title("Mean signal from ROI") -plt.xlabel("Time [s]") - -# calculating power spectrum -freqs, psd = el.spectral.welch_psd( - central_signal, fs=central_signal.sampling_rate, freq_res=0.1 * Hz, overlap=0.8 -) -plt.subplot(2, 2, 4) -plt.plot(freqs, np.mean(psd, axis=0), lw=0.8) -plt.title("Average power spectrum") -plt.xlabel("frequency [Hz]") -plt.ylabel("Fourier signal") - -plt.tight_layout() -plt.show() # see Figure 2 diff -Nru neo-0.10.0/examples/igorio.ipynb neo-0.10.2/examples/igorio.ipynb --- neo-0.10.0/examples/igorio.ipynb 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/examples/igorio.ipynb 2017-09-15 09:11:10.000000000 +0000 @@ -0,0 +1,130 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "## IgorProIO Demo" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import neo" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "### IBW support" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "data": { + "image/png": "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\nEZGY/j+DnKE7AWKkdQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Downloaded from Human Brain Project Collaboratory\n", + "# Digital Reconstruction of Neocortical Microcircuitry (nmc-portal)\n", + "# http://microcircuits.epfl.ch/#/animal/8ecde7d1-b2d2-11e4-b949-6003088da632\n", + "x = neo.io.IgorIO(filename='nmc-portal/grouped_ephys/B95/B95_Ch0_IDRest_107.ibw')\n", + "signal = x.read_analogsignal()\n", + "plt.plot(signal.times,signal)\n", + "plt.xlabel(signal.sampling_period.dimensionality)\n", + "plt.ylabel(signal.dimensionality);" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "### PXP support" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "data": { + "image/png": "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\nEZGY/j+DnKE7AWKkdQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Same as above, but the .ibw file was loaded into Igor and saved as part of a .pxp file. \n", + "x = neo.io.IgorIO(filename='nmc-portal/grouped_ephys/B95/B95_Ch0_IDRest_107.pxp')\n", + "signal = x.read_analogsignal(path='root:AA_IDRest_Ch0_107')\n", + "plt.plot(signal.times,signal)\n", + "plt.xlabel(signal.sampling_period.dimensionality)\n", + "plt.ylabel(signal.dimensionality);" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} Binary files /tmp/tmpr40tq30c/hb2sCGn_pC/neo-0.10.0/examples/nmc-portal/grouped_ephys/B95/B95_Ch0_IDRest_107.ibw and /tmp/tmpr40tq30c/WiNlIrMYeb/neo-0.10.2/examples/nmc-portal/grouped_ephys/B95/B95_Ch0_IDRest_107.ibw differ Binary files /tmp/tmpr40tq30c/hb2sCGn_pC/neo-0.10.0/examples/nmc-portal/grouped_ephys/B95/B95_Ch0_IDRest_107.pxp and /tmp/tmpr40tq30c/WiNlIrMYeb/neo-0.10.2/examples/nmc-portal/grouped_ephys/B95/B95_Ch0_IDRest_107.pxp differ diff -Nru neo-0.10.0/.gitignore neo-0.10.2/.gitignore --- neo-0.10.0/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/.gitignore 2020-12-16 11:06:26.000000000 +0000 @@ -0,0 +1,68 @@ +######################################### +# Editor temporary/working/backup files # +.#* +[#]*# +*~ +*$ +*.bak +*.kdev4 +*.komodoproject +*.orig +.project +.pydevproject +.settings +*.tmp* +.idea +*.swp +*.swo + +# Compiled source # +################### +*.a +*.com +*.class +*.dll +*.exe +*.mo +*.o +*.py[ocd] +*.so + +# Python files # +################ +# setup.py working directory +build +# other build directories +bin +dist +# sphinx build directory +doc/_build +# setup.py dist directory +dist +# Egg metadata +*.egg-info +*.egg +*.EGG +*.EGG-INFO +# tox testing tool +.tox +# coverage +.coverage +cover +*.ipynb_checkpoints + +# OS generated files # +###################### +.directory +.gdb_history +.DS_Store? +ehthumbs.db +Icon? +Thumbs.db + +# Things specific to this project # +################################### +neo/test/io/neurosharemergeio.py +files_for_testing_neo +/venv +/neo/test/resources diff -Nru neo-0.10.0/LICENSE.txt neo-0.10.2/LICENSE.txt --- neo-0.10.0/LICENSE.txt 2021-07-27 08:39:25.000000000 +0000 +++ neo-0.10.2/LICENSE.txt 2022-03-08 09:34:55.000000000 +0000 @@ -1,4 +1,4 @@ -Copyright (c) 2010-2021, Neo authors and contributors +Copyright (c) 2010-2022, Neo authors and contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff -Nru neo-0.10.0/neo/io/biocamio.py neo-0.10.2/neo/io/biocamio.py --- neo-0.10.0/neo/io/biocamio.py 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/neo/io/biocamio.py 2022-03-08 09:34:47.000000000 +0000 @@ -0,0 +1,11 @@ +from neo.io.basefromrawio import BaseFromRaw +from neo.rawio.biocamrawio import BiocamRawIO + + +class BiocamIO(BiocamRawIO, BaseFromRaw): + __doc__ = BiocamRawIO.__doc__ + mode = 'file' + + def __init__(self, filename): + BiocamRawIO.__init__(self, filename=filename) + BaseFromRaw.__init__(self, filename) diff -Nru neo-0.10.0/neo/io/__init__.py neo-0.10.2/neo/io/__init__.py --- neo-0.10.0/neo/io/__init__.py 2021-07-26 15:44:26.000000000 +0000 +++ neo-0.10.2/neo/io/__init__.py 2022-03-08 09:34:47.000000000 +0000 @@ -22,6 +22,7 @@ * :attr:`AxonaIO` * :attr:`AxonIO` * :attr:`BCI2000IO` +* :attr:`BiocamIO` * :attr:`BlackrockIO` * :attr:`BlkIO` * :attr:`BrainVisionIO` @@ -94,6 +95,10 @@ .. autoattribute:: extensions +.. autoclass:: neo.io.BiocamIO + + .. autoattribute:: extensions + .. autoclass:: neo.io.BlackrockIO .. autoattribute:: extensions @@ -277,6 +282,7 @@ from neo.io.axographio import AxographIO from neo.io.axonaio import AxonaIO from neo.io.axonio import AxonIO +from neo.io.biocamio import BiocamIO from neo.io.blackrockio import BlackrockIO from neo.io.blkio import BlkIO from neo.io.bci2000io import BCI2000IO diff -Nru neo-0.10.0/neo/io/neuralynxio.py neo-0.10.2/neo/io/neuralynxio.py --- neo-0.10.0/neo/io/neuralynxio.py 2021-06-10 15:35:20.000000000 +0000 +++ neo-0.10.2/neo/io/neuralynxio.py 2022-02-11 14:04:13.000000000 +0000 @@ -26,8 +26,8 @@ _prefered_signal_group_mode = 'group-by-same-units' mode = 'dir' - def __init__(self, dirname, use_cache=False, cache_path='same_as_resource', - keep_original_times=False): + def __init__(self, dirname='', filename='', use_cache=False, cache_path='same_as_resource', + exclude_filename=None, keep_original_times=False): """ Initialise IO instance @@ -41,11 +41,18 @@ cache_path : str, optional Folder path to use for cache files. Default: 'same_as_resource' + exclude_filename: str or list + Filename or list of filenames to be excluded. Expects base filenames without + directory path. keep_original_times : bool Preserve original time stamps as in data files. By default datasets are shifted to begin at t_start = 0*pq.second. Default: False """ - NeuralynxRawIO.__init__(self, dirname=dirname, use_cache=use_cache, - cache_path=cache_path, keep_original_times=keep_original_times) - BaseFromRaw.__init__(self, dirname) + NeuralynxRawIO.__init__(self, dirname=dirname, filename=filename, use_cache=use_cache, + cache_path=cache_path, exclude_filename=exclude_filename, + keep_original_times=keep_original_times) + if self.rawmode == 'one-file': + BaseFromRaw.__init__(self, filename) + elif self.rawmode == 'one-dir': + BaseFromRaw.__init__(self, dirname) diff -Nru neo-0.10.0/neo/io/nwbio.py neo-0.10.2/neo/io/nwbio.py --- neo-0.10.0/neo/io/nwbio.py 2021-07-26 15:44:26.000000000 +0000 +++ neo-0.10.2/neo/io/nwbio.py 2022-03-08 09:34:47.000000000 +0000 @@ -73,7 +73,8 @@ "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", "session_description" + "lab", "session_description", + "rec_datetime", ) POSSIBLE_JSON_FIELDS = ( @@ -273,7 +274,7 @@ "session_start_time"] if "file_create_date" in self.global_block_metadata: self.global_block_metadata["file_datetime"] = self.global_block_metadata[ - "file_create_date"] + "rec_datetime"] self._blocks = {} self._read_acquisition_group(lazy=lazy) @@ -435,11 +436,13 @@ annotations["session_description"] = blocks[0].description or self.filename # todo: concatenate descriptions of multiple blocks if different if "session_start_time" not in annotations: - raise Exception("Writing to NWB requires an annotation 'session_start_time'") + annotations["session_start_time"] = blocks[0].rec_datetime + if annotations["session_start_time"] is None: + raise Exception("Writing to NWB requires an annotation 'session_start_time'") + self.annotations = {"rec_datetime": "rec_datetime"} + self.annotations["rec_datetime"] = blocks[0].rec_datetime # todo: handle subject - # todo: store additional Neo annotations somewhere in NWB file nwbfile = NWBFile(**annotations) - assert self.nwb_file_mode in ('w',) # possibly expand to 'a'ppend later if self.nwb_file_mode == "w" and os.path.exists(self.filename): os.remove(self.filename) @@ -514,8 +517,11 @@ for i, signal in enumerate( chain(segment.analogsignals, segment.irregularlysampledsignals)): assert signal.segment is segment - if not signal.name: - signal.name = "%s : analogsignal%d" % (segment.name, i) + if hasattr(signal, 'name'): + signal.name = "%s %s %i" % (segment.name, signal.name, i) + logging.warning("Warning signal name exists. New name: %s" % (signal.name)) + else: + signal.name = "%s : analogsignal%s %i" % (segment.name, signal.name, i) self._write_signal(nwbfile, signal, electrodes) for i, train in enumerate(segment.spiketrains): @@ -526,8 +532,11 @@ for i, event in enumerate(segment.events): assert event.segment is segment - if not event.name: - event.name = "%s : event%d" % (segment.name, i) + if hasattr(event, 'name'): + event.name = "%s %s %i" % (segment.name, event.name, i) + logging.warning("Warning event name exists. New name: %s" % (event.name)) + else: + event.name = "%s : event%s %d" % (segment.name, event.name, i) self._write_event(nwbfile, event) for i, epoch in enumerate(segment.epochs): @@ -626,7 +635,8 @@ common_metadata_fields = ( # fields that are the same for all TimeSeries subclasses "comments", "description", "unit", "starting_time", "timestamps", "rate", - "data", "starting_time_unit", "timestamps_unit", "electrode" + "data", "starting_time_unit", "timestamps_unit", "electrode", + "stream_id", ) def __init__(self, timeseries, nwb_group): diff -Nru neo-0.10.0/neo/io/openephysbinaryio_old.py neo-0.10.2/neo/io/openephysbinaryio_old.py --- neo-0.10.0/neo/io/openephysbinaryio_old.py 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/neo/io/openephysbinaryio_old.py 2021-02-17 08:50:02.000000000 +0000 @@ -0,0 +1,11 @@ +from neo.io.basefromrawio import BaseFromRaw +from neo.rawio.openephysbinaryrawio import OpenEphysBinaryRawIO + + +class OpenEphysBinaryIO(OpenEphysBinaryRawIO, BaseFromRaw): + _prefered_signal_group_mode = 'group-by-same-units' + mode = 'dir' + + def __init__(self, dirname): + OpenEphysBinaryRawIO.__init__(self, dirname=dirname) + BaseFromRaw.__init__(self, dirname) diff -Nru neo-0.10.0/neo/io/proxyobjects.py neo-0.10.2/neo/io/proxyobjects.py --- neo-0.10.0/neo/io/proxyobjects.py 2021-07-26 15:44:26.000000000 +0000 +++ neo-0.10.2/neo/io/proxyobjects.py 2022-03-08 09:34:55.000000000 +0000 @@ -282,6 +282,10 @@ channel_indexes=fixed_chan_indexes) units = self.units + else: + raise ValueError(f'Invalid magnitude_mode {magnitude_mode}. Accepted values are ' + f'"rescaled" and "raw"') + anasig = AnalogSignal(sig, units=units, copy=False, t_start=sig_t_start, sampling_rate=self.sampling_rate, name=name, file_origin=self.file_origin, description=self.description, diff -Nru neo-0.10.0/neo/io/spikeglxio.py neo-0.10.2/neo/io/spikeglxio.py --- neo-0.10.0/neo/io/spikeglxio.py 2021-06-28 16:29:12.000000000 +0000 +++ neo-0.10.2/neo/io/spikeglxio.py 2022-03-08 09:34:47.000000000 +0000 @@ -6,6 +6,8 @@ __doc__ = SpikeGLXRawIO.__doc__ mode = 'dir' - def __init__(self, dirname): - SpikeGLXRawIO.__init__(self, dirname=dirname) + def __init__(self, dirname, load_sync_channel=False, load_channel_location=False): + SpikeGLXRawIO.__init__(self, dirname=dirname, + load_sync_channel=load_sync_channel, + load_channel_location=load_channel_location) BaseFromRaw.__init__(self, dirname) diff -Nru neo-0.10.0/neo/io/stimfitio.py neo-0.10.2/neo/io/stimfitio.py --- neo-0.10.0/neo/io/stimfitio.py 2021-06-10 15:35:20.000000000 +0000 +++ neo-0.10.2/neo/io/stimfitio.py 2022-03-08 09:34:55.000000000 +0000 @@ -32,15 +32,6 @@ from neo.io.baseio import BaseIO from neo.core import Block, Segment, AnalogSignal -try: - import stfio -except ImportError as err: - HAS_STFIO = False - STFIO_ERR = err -else: - HAS_STFIO = True - STFIO_ERR = None - class StimfitIO(BaseIO): """ @@ -99,8 +90,9 @@ Arguments: filename : Either a filename or a stfio Recording object """ - if not HAS_STFIO: - raise STFIO_ERR + # We need this module, so try importing now so that it fails on + # instantiation rather than read_block + import stfio # noqa BaseIO.__init__(self) @@ -112,6 +104,7 @@ self.filename = None def read_block(self, lazy=False): + import stfio assert not lazy, 'Do not support lazy' if self.filename is not None: diff -Nru neo-0.10.0/neo/rawio/axonarawio.py neo-0.10.2/neo/rawio/axonarawio.py --- neo-0.10.0/neo/rawio/axonarawio.py 2021-06-28 16:41:50.000000000 +0000 +++ neo-0.10.2/neo/rawio/axonarawio.py 2022-03-08 09:34:55.000000000 +0000 @@ -304,6 +304,9 @@ i_stop = bin_dict['num_total_samples'] if channel_indexes is None: channel_indexes = [i for i in range(bin_dict['num_channels'])] + elif isinstance(channel_indexes, slice): + channel_indexes_all = [i for i in range(bin_dict['num_channels'])] + channel_indexes = channel_indexes_all[channel_indexes] num_samples = (i_stop - i_start) diff -Nru neo-0.10.0/neo/rawio/biocamrawio.py neo-0.10.2/neo/rawio/biocamrawio.py --- neo-0.10.0/neo/rawio/biocamrawio.py 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/neo/rawio/biocamrawio.py 2022-03-08 09:34:55.000000000 +0000 @@ -0,0 +1,187 @@ +""" +Class for reading data from a 3-brain Biocam system. + +See: +https://www.3brain.com/products/single-well/biocam-x + +Author : Alessio Buccino +""" + +from .baserawio import (BaseRawIO, _signal_channel_dtype, _signal_stream_dtype, + _spike_channel_dtype, _event_channel_dtype) + +import numpy as np + +try: + import h5py + HAVE_H5PY = True +except ImportError: + HAVE_H5PY = False + + +class BiocamRawIO(BaseRawIO): + """ + Class for reading data from a Biocam h5 file. + + Usage: + >>> import neo.rawio + >>> r = neo.rawio.BiocamRawIO(filename='biocam.h5') + >>> r.parse_header() + >>> print(r) + >>> raw_chunk = r.get_analogsignal_chunk(block_index=0, seg_index=0, + i_start=0, i_stop=1024, + channel_names=channel_names) + >>> float_chunk = r.rescale_signal_raw_to_float(raw_chunk, dtype='float64', + channel_indexes=[0, 3, 6]) + """ + extensions = ['h5'] + rawmode = 'one-file' + + def __init__(self, filename=''): + BaseRawIO.__init__(self) + self.filename = filename + + def _source_name(self): + return self.filename + + def _parse_header(self): + assert HAVE_H5PY, 'h5py is not installed' + self._header_dict = open_biocam_file_header(self.filename) + self._num_channels = self._header_dict["num_channels"] + self._num_frames = self._header_dict["num_frames"] + self._sampling_rate = self._header_dict["sampling_rate"] + self._filehandle = self._header_dict["file_handle"] + self._read_function = self._header_dict["read_function"] + self._channels = self._header_dict["channels"] + gain = self._header_dict["gain"] + offset = self._header_dict["offset"] + + signal_streams = np.array([('Signals', '0')], dtype=_signal_stream_dtype) + + sig_channels = [] + for c, chan in enumerate(self._channels): + ch_name = f'ch{chan[0]}-{chan[1]}' + chan_id = str(c + 1) + sr = self._sampling_rate # Hz + dtype = "uint16" + units = 'uV' + gain = gain + offset = offset + stream_id = '0' + sig_channels.append((ch_name, chan_id, sr, dtype, units, gain, offset, stream_id)) + sig_channels = np.array(sig_channels, dtype=_signal_channel_dtype) + + # No events + event_channels = [] + event_channels = np.array(event_channels, dtype=_event_channel_dtype) + + # No spikes + spike_channels = [] + spike_channels = np.array(spike_channels, dtype=_spike_channel_dtype) + + self.header = {} + self.header['nb_block'] = 1 + self.header['nb_segment'] = [1] + self.header['signal_streams'] = signal_streams + self.header['signal_channels'] = sig_channels + self.header['spike_channels'] = spike_channels + self.header['event_channels'] = event_channels + + self._generate_minimal_annotations() + + def _segment_t_start(self, block_index, seg_index): + all_starts = [[0.]] + return all_starts[block_index][seg_index] + + def _segment_t_stop(self, block_index, seg_index): + t_stop = self._num_frames / self._sampling_rate + all_stops = [[t_stop]] + return all_stops[block_index][seg_index] + + def _get_signal_size(self, block_index, seg_index, stream_index): + assert stream_index == 0 + return self._num_frames + + def _get_signal_t_start(self, block_index, seg_index, stream_index): + assert stream_index == 0 + return self._segment_t_start(block_index, seg_index) + + def _get_analogsignal_chunk(self, block_index, seg_index, i_start, i_stop, + stream_index, channel_indexes): + if i_start is None: + i_start = 0 + if i_stop is None: + i_stop = self._num_frames + if channel_indexes is None: + channel_indexes = slice(None) + data = self._read_function(self._filehandle, i_start, i_stop, self._num_channels) + return data[:, channel_indexes] + + +def open_biocam_file_header(filename): + """Open a Biocam hdf5 file, read and return the recording info, pick te correct method to access raw data, + and return this to the caller.""" + assert HAVE_H5PY, 'h5py is not installed' + + rf = h5py.File(filename, 'r') + # Read recording variables + rec_vars = rf.require_group('3BRecInfo/3BRecVars/') + bit_depth = rec_vars['BitDepth'][0] + max_uv = rec_vars['MaxVolt'][0] + min_uv = rec_vars['MinVolt'][0] + n_frames = rec_vars['NRecFrames'][0] + sampling_rate = rec_vars['SamplingRate'][0] + signal_inv = rec_vars['SignalInversion'][0] + + # Get the actual number of channels used in the recording + file_format = rf['3BData'].attrs.get('Version', None) + format_100 = False + if file_format == 100: + n_channels = len(rf['3BData/Raw'][0]) + format_100 = True + elif file_format in (101, 102) or file_format is None: + n_channels = int(rf['3BData/Raw'].shape[0] / n_frames) + else: + raise Exception('Unknown data file format.') + + # # get channels + channels = rf['3BRecInfo/3BMeaStreams/Raw/Chs'][:] + + # determine correct function to read data + if format_100: + if signal_inv == 1: + read_function = readHDF5t_100 + elif signal_inv == 1: + read_function = readHDF5t_100_i + else: + raise Exception("Unknown signal inversion") + else: + if signal_inv == 1: + read_function = readHDF5t_101 + elif signal_inv == 1: + read_function = readHDF5t_101_i + else: + raise Exception("Unknown signal inversion") + + gain = (max_uv - min_uv) / (2 ** bit_depth) + offset = min_uv + + return dict(file_handle=rf, num_frames=n_frames, sampling_rate=sampling_rate, num_channels=n_channels, + channels=channels, file_format=file_format, signal_inv=signal_inv, + read_function=read_function, gain=gain, offset=offset) + + +def readHDF5t_100(rf, t0, t1, nch): + return rf['3BData/Raw'][t0:t1] + + +def readHDF5t_100_i(rf, t0, t1, nch): + return 4096 - rf['3BData/Raw'][t0:t1] + + +def readHDF5t_101(rf, t0, t1, nch): + return rf['3BData/Raw'][nch * t0:nch * t1].reshape((t1 - t0, nch), order='C') + + +def readHDF5t_101_i(rf, t0, t1, nch): + return 4096 - rf['3BData/Raw'][nch * t0:nch * t1].reshape((t1 - t0, nch), order='C') diff -Nru neo-0.10.0/neo/rawio/__init__.py neo-0.10.2/neo/rawio/__init__.py --- neo-0.10.0/neo/rawio/__init__.py 2021-07-26 12:48:41.000000000 +0000 +++ neo-0.10.2/neo/rawio/__init__.py 2022-03-08 09:34:47.000000000 +0000 @@ -15,6 +15,7 @@ * :attr:`AxographRawIO` * :attr:`AxonaRawIO` * :attr:`AxonRawIO` +* :attr:`BiocamRawIO` * :attr:`BlackrockRawIO` * :attr:`BrainVisionRawIO` * :attr:`CedRawIO` @@ -53,6 +54,10 @@ .. autoattribute:: extensions +.. autoclass:: neo.rawio.BiocamRawIO + + .. autoattribute:: extensions + .. autoclass:: neo.rawio.BlackrockRawIO .. autoattribute:: extensions @@ -155,6 +160,7 @@ from neo.rawio.axographrawio import AxographRawIO from neo.rawio.axonarawio import AxonaRawIO from neo.rawio.axonrawio import AxonRawIO +from neo.rawio.biocamrawio import BiocamRawIO from neo.rawio.blackrockrawio import BlackrockRawIO from neo.rawio.brainvisionrawio import BrainVisionRawIO from neo.rawio.cedrawio import CedRawIO @@ -185,6 +191,7 @@ AxographRawIO, AxonaRawIO, AxonRawIO, + BiocamRawIO, BlackrockRawIO, BrainVisionRawIO, CedRawIO, diff -Nru neo-0.10.0/neo/rawio/maxwellrawio.py neo-0.10.2/neo/rawio/maxwellrawio.py --- neo-0.10.0/neo/rawio/maxwellrawio.py 2021-07-26 15:44:26.000000000 +0000 +++ neo-0.10.2/neo/rawio/maxwellrawio.py 2022-03-08 09:34:55.000000000 +0000 @@ -23,7 +23,7 @@ from urllib.request import urlopen from .baserawio import (BaseRawIO, _signal_channel_dtype, _signal_stream_dtype, - _spike_channel_dtype, _event_channel_dtype) + _spike_channel_dtype, _event_channel_dtype) import numpy as np @@ -75,13 +75,15 @@ rec_names = list(h5['wells'][stream_id].keys()) if len(rec_names) > 1: if self.rec_name is None: - raise ValueError("Detected multiple recordings. Please select a single recording using" - f' the `rec_name` paramter.\nPossible rec_name {rec_names}') + raise ValueError("Detected multiple recordings. Please select a " + "single recording using the `rec_name` paramter. " + f"Possible rec_name {rec_names}") else: self.rec_name = rec_names[0] signal_streams.append((stream_id, stream_id)) else: - raise NotImplementedError(f'This version {version} is not supported') + raise NotImplementedError( + f'This version {version} is not supported') signal_streams = np.array(signal_streams, dtype=_signal_stream_dtype) # create signal channels @@ -185,15 +187,31 @@ if i_stop is None: i_stop = sigs.shape[1] + resorted_indexes = None if channel_indexes is None: channel_indexes = slice(None) + else: + if np.array(channel_indexes).size > 1 and np.any(np.diff(channel_indexes) < 0): + # get around h5py constraint that it does not allow datasets + # to be indexed out of order + sorted_channel_indexes = np.sort(channel_indexes) + resorted_indexes = np.array( + [list(channel_indexes).index(ch) for ch in sorted_channel_indexes]) try: - if self._old_format: - sigs = sigs[self._channel_slice, i_start:i_stop] - sigs = sigs[channel_indexes] + if resorted_indexes is None: + if self._old_format: + sigs = sigs[self._channel_slice, i_start:i_stop] + sigs = sigs[channel_indexes] + else: + sigs = sigs[channel_indexes, i_start:i_stop] else: - sigs = sigs[channel_indexes, i_start:i_stop] + if self._old_format: + sigs = sigs[self._channel_slice, i_start:i_stop] + sigs = sigs[sorted_channel_indexes] + else: + sigs = sigs[sorted_channel_indexes, i_start:i_stop] + sigs = sigs[resorted_indexes] except OSError as e: print('*' * 10) print(_hdf_maxwell_error) diff -Nru neo-0.10.0/neo/rawio/neuralynxrawio/ncssections.py neo-0.10.2/neo/rawio/neuralynxrawio/ncssections.py --- neo-0.10.0/neo/rawio/neuralynxrawio/ncssections.py 2021-06-28 16:41:50.000000000 +0000 +++ neo-0.10.2/neo/rawio/neuralynxrawio/ncssections.py 2022-02-11 14:04:13.000000000 +0000 @@ -1,4 +1,5 @@ import math +import numpy as np class NcsSections: @@ -7,7 +8,7 @@ Methods of NcsSectionsFactory perform parsing of this information from an Ncs file and produce these where the sections are discontiguous in time and in temporal order. - TODO: This class will likely need __eq__, __ne__, and __hash__ to be useful in + TODO: This class will likely need __ne__ to be useful in more sophisticated segment construction algorithms. """ @@ -16,6 +17,16 @@ self.sampFreqUsed = 0 # actual sampling frequency of samples self.microsPerSampUsed = 0 # microseconds per sample + def __eq__(self, other): + samp_eq = self.sampFreqUsed == other.sampFreqUsed + micros_eq = self.microsPerSampUsed == other.microsPerSampUsed + sects_eq = self.sects == other.sects + return (samp_eq and micros_eq and sects_eq) + + def __hash__(self): + return (f'{self.sampFreqUsed};{self.microsPerSampUsed};' + f'{[s.__hash__() for s in self.sects]}').__hash__() + class NcsSection: """ @@ -37,11 +48,23 @@ self.endTime = -1 # end time of last record, that is, the end time of the last # sampling period contained in the last record of the section - def __init__(self, sb, st, eb, et): + def __init__(self, sb, st, eb, et, ns): self.startRec = sb self.startTime = st self.endRec = eb self.endTime = et + self.n_samples = ns + + def __eq__(self, other): + return (self.startRec == other.startRec + and self.startTime == other.startTime + and self.endRec == other.endRec + and self.endTime == other.endTime + and self.n_samples == other.n_samples) + + def __hash__(self): + s = f'{self.startRec};{self.startTime};{self.endRec};{self.endTime};{self.n_samples}' + return s.__hash__() def before_time(self, rhb): """ @@ -124,32 +147,38 @@ NcsSections object with block locations marked """ startBlockPredTime = blkOnePredTime - blkLen = 0 + blk_len = 0 curBlock = ncsSects.sects[0] for recn in range(1, ncsMemMap.shape[0]): - if ncsMemMap['channel_id'][recn] != chanNum or \ - ncsMemMap['sample_rate'][recn] != reqFreq: + timestamp = ncsMemMap['timestamp'][recn] + channel_id = ncsMemMap['channel_id'][recn] + sample_rate = ncsMemMap['sample_rate'][recn] + nb_valid = ncsMemMap['nb_valid'][recn] + + if channel_id != chanNum or sample_rate != reqFreq: raise IOError('Channel number or sampling frequency changed in ' + 'records within file') predTime = NcsSectionsFactory.calc_sample_time(ncsSects.sampFreqUsed, - startBlockPredTime, blkLen) - ts = ncsMemMap['timestamp'][recn] - nValidSamps = ncsMemMap['nb_valid'][recn] - if ts != predTime: + startBlockPredTime, blk_len) + nValidSamps = nb_valid + if timestamp != predTime: curBlock.endRec = recn - 1 curBlock.endTime = predTime - curBlock = NcsSection(recn, ts, -1, -1) + curBlock.n_samples = blk_len + curBlock = NcsSection(recn, timestamp, -1, -1, -1) ncsSects.sects.append(curBlock) startBlockPredTime = NcsSectionsFactory.calc_sample_time( - ncsSects.sampFreqUsed, ts, nValidSamps) - blkLen = 0 + ncsSects.sampFreqUsed, + timestamp, + nValidSamps) + blk_len = 0 else: - blkLen += nValidSamps + blk_len += nValidSamps curBlock.endRec = ncsMemMap.shape[0] - 1 endTime = NcsSectionsFactory.calc_sample_time(ncsSects.sampFreqUsed, startBlockPredTime, - blkLen) + blk_len) curBlock.endTime = endTime return ncsSects @@ -199,7 +228,8 @@ ncsMemMap['sample_rate'][lastBlkI] == reqFreq and \ lts == predLastBlockStartTime: lastBlkEndTime = NcsSectionsFactory.calc_sample_time(actualSampFreq, lts, lnb) - curBlock = NcsSection(0, ts0, lastBlkI, lastBlkEndTime) + n_samples = NcsSection._RECORD_SIZE * lastBlkI + curBlock = NcsSection(0, ts0, lastBlkI, lastBlkEndTime, n_samples) nb.sects.append(curBlock) return nb @@ -207,7 +237,7 @@ # otherwise need to scan looking for breaks else: blkOnePredTime = NcsSectionsFactory.calc_sample_time(actualSampFreq, ts0, nb0) - curBlock = NcsSection(0, ts0, -1, -1) + curBlock = NcsSection(0, ts0, -1, -1, -1) nb.sects.append(curBlock) return NcsSectionsFactory._parseGivenActualFrequency(ncsMemMap, nb, chanNum, reqFreq, blkOnePredTime) @@ -233,60 +263,72 @@ largest block """ - # track frequency of each block and use estimate with longest block - maxBlkLen = 0 - maxBlkFreqEstimate = 0 - - # Parse the record sequence, finding blocks of continuous time with no more than - # maxGapLength and same channel number chanNum = ncsMemMap['channel_id'][0] - - startBlockTime = ncsMemMap['timestamp'][0] - blkLen = ncsMemMap['nb_valid'][0] - lastRecTime = startBlockTime - lastRecNumSamps = blkLen recFreq = ncsMemMap['sample_rate'][0] - curBlock = NcsSection(0, startBlockTime, -1, -1) - ncsSects.sects.append(curBlock) - for recn in range(1, ncsMemMap.shape[0]): - if ncsMemMap['channel_id'][recn] != chanNum or \ - ncsMemMap['sample_rate'][recn] != recFreq: - raise IOError('Channel number or sampling frequency changed in ' + - 'records within file') - predTime = NcsSectionsFactory.calc_sample_time(ncsSects.sampFreqUsed, lastRecTime, - lastRecNumSamps) - ts = ncsMemMap['timestamp'][recn] - nb = ncsMemMap['nb_valid'][recn] - if abs(ts - predTime) > maxGapLen: - curBlock.endRec = recn - 1 - curBlock.endTime = predTime - curBlock = NcsSection(recn, ts, -1, -1) - ncsSects.sects.append(curBlock) - if blkLen > maxBlkLen: - maxBlkLen = blkLen - maxBlkFreqEstimate = (blkLen - lastRecNumSamps) * 1e6 / \ - (lastRecTime - startBlockTime) - startBlockTime = ts - blkLen = nb - else: - blkLen += nb - lastRecTime = ts - lastRecNumSamps = nb - - if blkLen > maxBlkLen: - maxBlkFreqEstimate = (blkLen - lastRecNumSamps) * 1e6 / \ - (lastRecTime - startBlockTime) + # check for consistent channel_ids and sampling rates + ncsMemMap['channel_id'] + if not (ncsMemMap['channel_id'] == chanNum).all(): + raise IOError('Channel number changed in records within file') + + if not all(ncsMemMap['sample_rate'] == recFreq): + raise IOError('Sampling frequency changed in records within file') + + # find most frequent number of samples + exp_nb_valid = np.argmax(np.bincount(ncsMemMap['nb_valid'])) + # detect records with incomplete number of samples + gap_rec_ids = list(np.where(ncsMemMap['nb_valid'] != exp_nb_valid)[0]) + + rec_duration = 1e6 / ncsSects.sampFreqUsed * ncsMemMap['nb_valid'] + pred_times = np.rint(ncsMemMap['timestamp'] + rec_duration).astype(np.int64) + max_pred_times = pred_times + maxGapLen + # data records that start later than the predicted time (including the + # maximal accepted gap length) are considered delayed and a gap is + # registered. + delayed_recs = list(np.where(max_pred_times[:-1] < ncsMemMap['timestamp'][1:])[0]) + gap_rec_ids.extend(delayed_recs) + + # cleaning extracted gap ids + # last record can not be the beginning of a gap + last_rec_id = len(ncsMemMap['timestamp']) - 1 + if last_rec_id in gap_rec_ids: + gap_rec_ids.remove(last_rec_id) + + # gap ids can only be listed once + gap_rec_ids = sorted(set(gap_rec_ids)) + + # create recording segments from identified gaps + ncsSects.sects.append(NcsSection(0, ncsMemMap['timestamp'][0], -1, -1, -1)) + for gap_rec_id in gap_rec_ids: + curr_sec = ncsSects.sects[-1] + curr_sec.endRec = gap_rec_id + curr_sec.endTime = pred_times[gap_rec_id] + n_samples = np.sum(ncsMemMap['nb_valid'][curr_sec.startRec:gap_rec_id + 1]) + curr_sec.n_samples = n_samples + + next_sec = NcsSection(gap_rec_id + 1, + ncsMemMap['timestamp'][gap_rec_id + 1], -1, -1, -1) + ncsSects.sects.append(next_sec) + + curr_sec = ncsSects.sects[-1] + curr_sec.endRec = len(ncsMemMap['timestamp']) - 1 + curr_sec.endTime = pred_times[-1] + n_samples = np.sum(ncsMemMap['nb_valid'][curr_sec.startRec:]) + curr_sec.n_samples = n_samples + + # calculate the estimated frequency of the block with the most samples + max_blk_idx = np.argmax([bl.endRec - bl.startRec for bl in ncsSects.sects]) + max_blk = ncsSects.sects[max_blk_idx] - curBlock.endRec = ncsMemMap.shape[0] - 1 - endTime = NcsSectionsFactory.calc_sample_time(ncsSects.sampFreqUsed, lastRecTime, - lastRecNumSamps) - curBlock.endTime = endTime + maxBlkFreqEstimate = (max_blk.n_samples - ncsMemMap['nb_valid'][max_blk.endRec]) * 1e6 / \ + (ncsMemMap['timestamp'][max_blk.endRec] - max_blk.startTime) ncsSects.sampFreqUsed = maxBlkFreqEstimate ncsSects.microsPerSampUsed = NcsSectionsFactory.get_micros_per_samp_for_freq( maxBlkFreqEstimate) - + # free memory that is unnecessarily occupied by the memmap + # (see https://github.com/numpy/numpy/issues/19340) + del ncsMemMap return ncsSects @staticmethod @@ -325,7 +367,7 @@ freqInFile = math.floor(nomFreq) if lts - predLastBlockStartTime == 0 and lcid == chanNum and lsr == freqInFile: endTime = NcsSectionsFactory.calc_sample_time(nomFreq, lts, lnb) - curBlock = NcsSection(0, ts0, lastBlkI, endTime) + curBlock = NcsSection(0, ts0, lastBlkI, endTime, numSampsForPred) nb.sects.append(curBlock) nb.sampFreqUsed = numSampsForPred / (lts - ts0) * 1e6 nb.microsPerSampUsed = NcsSectionsFactory.get_micros_per_samp_for_freq(nb.sampFreqUsed) diff -Nru neo-0.10.0/neo/rawio/neuralynxrawio/neuralynxrawio.py neo-0.10.2/neo/rawio/neuralynxrawio/neuralynxrawio.py --- neo-0.10.0/neo/rawio/neuralynxrawio/neuralynxrawio.py 2021-07-26 12:48:41.000000000 +0000 +++ neo-0.10.2/neo/rawio/neuralynxrawio/neuralynxrawio.py 2022-02-11 14:04:13.000000000 +0000 @@ -47,6 +47,8 @@ import numpy as np import os +import pathlib +import copy from collections import (namedtuple, OrderedDict) from neo.rawio.neuralynxrawio.ncssections import (NcsSection, NcsSectionsFactory) @@ -76,7 +78,8 @@ _ncs_dtype = [('timestamp', 'uint64'), ('channel_id', 'uint32'), ('sample_rate', 'uint32'), ('nb_valid', 'uint32'), ('samples', 'int16', (NcsSection._RECORD_SIZE))] - def __init__(self, dirname='', filename='', keep_original_times=False, **kargs): + def __init__(self, dirname='', filename='', exclude_filename=None, keep_original_times=False, + **kargs): """ Initialize io for either a directory of Ncs files or a single Ncs file. @@ -88,6 +91,9 @@ filename: str name of a single ncs, nse, nev, or ntt file to include in dataset. If used, dirname must not be provided. + exclude_filename: str or list + name of a single ncs, nse, nev or ntt file or list of such files. Expects plain + filenames (without directory path). keep_original_times: if True, keep original start time as in files, otherwise set 0 of time to first time in dataset @@ -102,6 +108,7 @@ raise ValueError("One of dirname or filename must be provided.") self.keep_original_times = keep_original_times + self.exclude_filename = exclude_filename BaseRawIO.__init__(self, **kargs) def _source_name(self): @@ -110,6 +117,9 @@ else: return self.dirname + # from memory_profiler import profile + # + # @profile() def _parse_header(self): stream_channels = [] @@ -139,9 +149,23 @@ filenames = sorted(os.listdir(self.dirname)) dirname = self.dirname else: + if not os.path.isfile(self.filename): + raise ValueError(f'Provided Filename is not a file: ' + f'{self.filename}. If you want to provide a ' + f'directory use the `dirname` keyword') + dirname, fname = os.path.split(self.filename) filenames = [fname] + if not isinstance(self.exclude_filename, (list, set, np.ndarray)): + self.exclude_filename = [self.exclude_filename] + + # remove files that were explicitly excluded + if self.exclude_filename is not None: + for excl_file in self.exclude_filename: + if excl_file in filenames: + filenames.remove(excl_file) + for filename in filenames: filename = os.path.join(dirname, filename) @@ -209,15 +233,7 @@ 'Several nse or ntt files have the same unit_id!!!' self.nse_ntt_filenames[chan_uid] = filename - dtype = get_nse_or_ntt_dtype(info, ext) - - if os.path.getsize(filename) <= NlxHeader.HEADER_SIZE: - self._empty_nse_ntt.append(filename) - data = np.zeros((0,), dtype=dtype) - else: - data = np.memmap(filename, dtype=dtype, mode='r', - offset=NlxHeader.HEADER_SIZE) - + data = self._get_file_map(filename) self._spike_memmap[chan_uid] = data unit_ids = np.unique(data['unit_id']) @@ -249,8 +265,7 @@ data = np.zeros((0,), dtype=nev_dtype) internal_ids = [] else: - data = np.memmap(filename, dtype=nev_dtype, mode='r', - offset=NlxHeader.HEADER_SIZE) + data = self._get_file_map(filename) internal_ids = np.unique(data[['event_id', 'ttl_input']]).tolist() for internal_event_id in internal_ids: if internal_event_id not in self.internal_event_ids: @@ -378,6 +393,37 @@ # ~ ev_ann['digital_marker'] = # ~ ev_ann['analog_marker'] = + def _get_file_map(self, filename): + """ + Create memory maps when needed + see also https://github.com/numpy/numpy/issues/19340 + """ + filename = pathlib.Path(filename) + suffix = filename.suffix.lower()[1:] + + if suffix == 'ncs': + return np.memmap(filename, dtype=self._ncs_dtype, mode='r', + offset=NlxHeader.HEADER_SIZE) + + elif suffix in ['nse', 'ntt']: + info = NlxHeader(filename) + dtype = get_nse_or_ntt_dtype(info, suffix) + + # return empty map if file does not contain data + if os.path.getsize(filename) <= NlxHeader.HEADER_SIZE: + self._empty_nse_ntt.append(filename) + return np.zeros((0,), dtype=dtype) + + return np.memmap(filename, dtype=dtype, mode='r', + offset=NlxHeader.HEADER_SIZE) + + elif suffix == 'nev': + return np.memmap(filename, dtype=nev_dtype, mode='r', + offset=NlxHeader.HEADER_SIZE) + + else: + raise ValueError(f'Unknown file suffix {suffix}') + # Accessors for segment times which are offset by appropriate global start time def _segment_t_start(self, block_index, seg_index): return self._seg_t_starts[seg_index] - self.global_t_start @@ -565,16 +611,15 @@ chanSectMap = dict() for chan_uid, ncs_filename in self.ncs_filenames.items(): - data = np.memmap(ncs_filename, dtype=self._ncs_dtype, mode='r', - offset=NlxHeader.HEADER_SIZE) + data = self._get_file_map(ncs_filename) nlxHeader = NlxHeader(ncs_filename) if not chanSectMap or (chanSectMap and not NcsSectionsFactory._verifySectionsStructure(data, lastNcsSections)): lastNcsSections = NcsSectionsFactory.build_for_ncs_file(data, nlxHeader) - - chanSectMap[chan_uid] = [lastNcsSections, nlxHeader, data] + chanSectMap[chan_uid] = [lastNcsSections, nlxHeader, ncs_filename] + del data # Construct an inverse dictionary from NcsSections to list of associated chan_uids revSectMap = dict() @@ -584,8 +629,8 @@ # If there is only one NcsSections structure in the set of ncs files, there should only # be one entry. Otherwise this is presently unsupported. if len(revSectMap) > 1: - raise IOError('ncs files have {} different sections structures. Unsupported.'.format( - len(revSectMap))) + raise IOError(f'ncs files have {len(revSectMap)} different sections ' + f'structures. Unsupported configuration.') seg_time_limits = SegmentTimeLimits(nb_segment=len(lastNcsSections.sects), t_start=[], t_stop=[], length=[], @@ -595,7 +640,7 @@ # create segment with subdata block/t_start/t_stop/length for each channel for i, fileEntry in enumerate(self.ncs_filenames.items()): chan_uid = fileEntry[0] - data = chanSectMap[chan_uid][2] + data = self._get_file_map(chanSectMap[chan_uid][2]) # create a memmap for each record section of the current file curSects = chanSectMap[chan_uid][0] diff -Nru neo-0.10.0/neo/rawio/neuroscoperawio.py neo-0.10.2/neo/rawio/neuroscoperawio.py --- neo-0.10.0/neo/rawio/neuroscoperawio.py 2021-06-28 16:29:12.000000000 +0000 +++ neo-0.10.2/neo/rawio/neuroscoperawio.py 2022-03-08 09:34:55.000000000 +0000 @@ -73,7 +73,7 @@ # signals sig_channels = [] for c in range(nb_channel): - name = 'ch{}grp{}'.format(c, channel_group[c]) + name = 'ch{}grp{}'.format(c, channel_group.get(c, 'none')) chan_id = str(c) units = 'mV' offset = 0. diff -Nru neo-0.10.0/neo/rawio/openephysbinaryrawio.py neo-0.10.2/neo/rawio/openephysbinaryrawio.py --- neo-0.10.0/neo/rawio/openephysbinaryrawio.py 2021-06-28 16:29:12.000000000 +0000 +++ neo-0.10.2/neo/rawio/openephysbinaryrawio.py 2022-03-08 09:34:55.000000000 +0000 @@ -98,7 +98,6 @@ for seg_index in range(nb_segment_per_block[block_index]): for stream_index, d in self._sig_streams[block_index][seg_index].items(): num_channels = len(d['channels']) - print(d['raw_filename']) memmap_sigs = np.memmap(d['raw_filename'], d['dtype'], order='C', mode='r').reshape(-1, num_channels) d['memmap'] = memmap_sigs @@ -337,7 +336,7 @@ # so no node_name node_name = '' - block_index = int(root.parents[0].stem.replace('experiment', '')) - 1 + block_index = int(root.parents[0].stem.lower().replace('experiment', '')) - 1 if block_index not in all_streams: all_streams[block_index] = {} if block_index >= nb_block: diff -Nru neo-0.10.0/neo/rawio/spikeglxrawio.py neo-0.10.2/neo/rawio/spikeglxrawio.py --- neo-0.10.0/neo/rawio/spikeglxrawio.py 2021-06-28 16:41:50.000000000 +0000 +++ neo-0.10.2/neo/rawio/spikeglxrawio.py 2022-03-08 09:34:47.000000000 +0000 @@ -35,6 +35,11 @@ https://billkarsh.github.io/SpikeGLX/#metadata-guides https://github.com/SpikeInterface/spikeextractors/blob/master/spikeextractors/extractors/spikeglxrecordingextractor/spikeglxrecordingextractor.py +This reader handle: + +imDatPrb_type=1 (NP 1.0) +imDatPrb_type=21 (NP 2.0, single multiplexed shank) +imDatPrb_type=24 (NP 2.0, 4-shank) Author : Samuel Garcia """ @@ -52,13 +57,20 @@ class SpikeGLXRawIO(BaseRawIO): """ Class for reading data from a SpikeGLX system + + dirname: + The spikeglx folder containing meta/bin files + load_sync_channel=False/True + The last channel (SY0) of each stream is a fake channel used for synchronisation. """ extensions = [] rawmode = 'one-dir' - def __init__(self, dirname=''): + def __init__(self, dirname='', load_sync_channel=False, load_channel_location=False): BaseRawIO.__init__(self) self.dirname = dirname + self.load_sync_channel = load_sync_channel + self.load_channel_location = load_channel_location def _source_name(self): return self.dirname @@ -80,8 +92,10 @@ self.signals_info_dict[key] = info # create memmap - data = np.memmap(info['bin_file'], dtype='int16', mode='r', - shape=(info['sample_length'], info['num_chan']), offset=0, order='C') + data = np.memmap(info['bin_file'], dtype='int16', mode='r', offset=0, order='C') + # this should be (info['sample_length'], info['num_chan']) + # be some file are shorten + data = data.reshape(-1, info['num_chan']) self._memmaps[key] = data # create channel header @@ -102,6 +116,8 @@ signal_channels.append((chan_name, chan_id, info['sampling_rate'], 'int16', info['units'], info['channel_gains'][local_chan], info['channel_offsets'][local_chan], stream_id)) + if not self.load_sync_channel: + signal_channels = signal_channels[:-1] signal_streams = np.array(signal_streams, dtype=_signal_stream_dtype) signal_channels = np.array(signal_channels, dtype=_signal_channel_dtype) @@ -145,14 +161,19 @@ stream_name = signal_stream['name'] sig_ann = self.raw_annotations['blocks'][0]['segments'][seg_index]['signals'][c] - # channel location - info = self.signals_info_dict[seg_index, stream_name] - if 'channel_location' in info: - loc = info['channel_location'] - # one fake channel for "sys0" - loc = np.concatenate((loc, [[0., 0.]]), axis=0) - for ndim in range(loc.shape[1]): - sig_ann['__array_annotations__'][f'channel_location_{ndim}'] = loc[:, ndim] + if self.load_channel_location: + # need probeinterface to be installed + import probeinterface + info = self.signals_info_dict[seg_index, stream_name] + if 'imroTbl' in info['meta'] and info['signal_kind'] == 'ap': + # only for ap channel + probe = probeinterface.read_spikeglx(info['meta_file']) + loc = probe.contact_positions + if self.load_sync_channel: + # one fake channel for "sys0" + loc = np.concatenate((loc, [[0., 0.]]), axis=0) + for ndim in range(loc.shape[1]): + sig_ann['__array_annotations__'][f'channel_location_{ndim}'] = loc[:, ndim] def _segment_t_start(self, block_index, seg_index): return 0. @@ -172,17 +193,38 @@ stream_index, channel_indexes): stream_id = self.header['signal_streams'][stream_index]['id'] memmap = self._memmaps[seg_index, stream_id] - if channel_indexes is None: - channel_indexes = slice(channel_indexes) - - if not isinstance(channel_indexes, slice): + if self.load_sync_channel: + channel_selection = slice(None) + else: + channel_selection = slice(-1) + elif isinstance(channel_indexes, slice): + if self.load_sync_channel: + # simple + channel_selection = channel_indexes + else: + # more tricky because negative + sl_start = channel_indexes.start + sl_stop = channel_indexes.stop + sl_step = channel_indexes.step + if sl_stop is not None and sl_stop < 0: + sl_stop = sl_stop - 1 + elif sl_stop is None: + sl_stop = -1 + channel_selection = slice(sl_start, sl_stop, sl_step) + elif not isinstance(channel_indexes, slice): if np.all(np.diff(channel_indexes) == 1): # consecutive channel then slice this avoid a copy (because of ndarray.take(...) # and so keep the underlying memmap - local_chans = slice(channel_indexes[0], channel_indexes[0] + len(channel_indexes)) + channel_selection = slice(channel_indexes[0], + channel_indexes[0] + len(channel_indexes)) + else: + channel_selection = channel_indexes + else: + raise ValueError('get_analogsignal_chunk : channel_indexes' + 'must be slice or list or array of int') - raw_signals = memmap[slice(i_start, i_stop), channel_indexes] + raw_signals = memmap[slice(i_start, i_stop), channel_selection] return raw_signals @@ -210,11 +252,11 @@ # Example file name structure: # Consider the filenames: `Noise4Sam_g0_t0.nidq.bin` or `Noise4Sam_g0_t0.imec0.lf.bin` # The filenames consist of 3 or 4 parts separated by `.` - #  * "Noise4Sam_g0_t0" will be the `name` variable. This choosen by the user - # at recording time. - #  * "_gt0_" will give the `seg_index` (here 0) - # * "nidq" or "imec0" will give the `device` variable - # * "lf" or "ap" will be the `signal_kind` variable + # 1. "Noise4Sam_g0_t0" will be the `name` variable. This choosen by the user + # at recording time. + # 2. "_gt0_" will give the `seg_index` (here 0) + # 3. "nidq" or "imec0" will give the `device` variable + # 4. "lf" or "ap" will be the `signal_kind` variable # `stream_name` variable is the concatenation of `device.signal_kind` name = file.split('.')[0] r = re.findall(r'_g(\d*)_t', name) @@ -229,16 +271,31 @@ # metad['imroTbl'] contain two gain per channel AP and LF # except for the last fake channel per_channel_gain = np.ones(num_chan, dtype='float64') - if signal_kind == 'ap': - index_imroTbl = 3 - elif signal_kind == 'lf': - index_imroTbl = 4 - # the last channel doesn't have a gain value - for c in range(num_chan - 1): - per_channel_gain[c] = 1. / float(meta['imroTbl'][c].split(' ')[index_imroTbl]) - gain_factor = float(meta['imAiRangeMax']) / 512 - channel_gains = per_channel_gain * gain_factor * 1e6 - + if 'imDatPrb_type' not in meta or meta['imDatPrb_type'] == '0': + # This work with NP 1.0 case with different metadata versions + # https://github.com/billkarsh/SpikeGLX/blob/gh-pages/Support/Metadata_3A.md#imec + # https://github.com/billkarsh/SpikeGLX/blob/gh-pages/Support/Metadata_3B1.md#imec + # https://github.com/billkarsh/SpikeGLX/blob/gh-pages/Support/Metadata_3B2.md#imec + if signal_kind == 'ap': + index_imroTbl = 3 + elif signal_kind == 'lf': + index_imroTbl = 4 + for c in range(num_chan - 1): + v = meta['imroTbl'][c].split(' ')[index_imroTbl] + per_channel_gain[c] = 1. / float(v) + gain_factor = float(meta['imAiRangeMax']) / 512 + channel_gains = gain_factor * per_channel_gain * 1e6 + elif meta['imDatPrb_type'] in ('21', '24') and signal_kind == 'ap': + # This work with NP 2.0 case with different metadata versions + # https://github.com/billkarsh/SpikeGLX/blob/gh-pages/Support/Metadata_20.md#channel-entries-by-type + # https://github.com/billkarsh/SpikeGLX/blob/gh-pages/Support/Metadata_20.md#imec + # https://github.com/billkarsh/SpikeGLX/blob/gh-pages/Support/Metadata_30.md#imec + per_channel_gain[:-1] = 1 / 80. + gain_factor = float(meta['imAiRangeMax']) / 8192 + channel_gains = gain_factor * per_channel_gain * 1e6 + else: + raise NotImplementedError('This meta file version of spikeglx' + 'is not implemented') else: signal_kind = '' stream_name = device @@ -248,8 +305,8 @@ # there are differents kinds of channels with different gain values mn, ma, xa, dw = [int(e) for e in meta['snsMnMaXaDw'].split(sep=',')] per_channel_gain = np.ones(num_chan, dtype='float64') - per_channel_gain[0:mn] = float(meta['niMNGain']) - per_channel_gain[mn:mn + ma] = float(meta['niMAGain']) + per_channel_gain[0:mn] = 1. / float(meta['niMNGain']) + per_channel_gain[mn:mn + ma] = 1. / float(meta['niMAGain']) # this scaling come from the code in this zip # https://billkarsh.github.io/SpikeGLX/Support/SpikeGLX_Datafile_Tools.zip # in file readSGLX.py line76 @@ -260,6 +317,7 @@ info = {} info['name'] = name info['meta'] = meta + info['meta_file'] = str(meta_filename) info['bin_file'] = str(bin_filename) for k in ('niSampRate', 'imSampRate'): if k in meta: @@ -276,15 +334,6 @@ info['channel_gains'] = channel_gains info['channel_offsets'] = np.zeros(info['num_chan']) - if signal_kind == 'ap': - channel_location = [] - for e in meta['snsShankMap']: - x_pos = int(e.split(':')[1]) - y_pos = int(e.split(':')[2]) - channel_location.append([x_pos, y_pos]) - - info['channel_location'] = np.array(channel_location) - info_list.append(info) return info_list diff -Nru neo-0.10.0/neo/rawio/tdtrawio.py neo-0.10.2/neo/rawio/tdtrawio.py --- neo-0.10.0/neo/rawio/tdtrawio.py 2021-06-28 16:41:50.000000000 +0000 +++ neo-0.10.2/neo/rawio/tdtrawio.py 2022-03-08 09:34:55.000000000 +0000 @@ -28,7 +28,9 @@ import numpy as np import os import re +import warnings from collections import OrderedDict +from pathlib import Path class TdtRawIO(BaseRawIO): @@ -36,41 +38,65 @@ def __init__(self, dirname='', sortname=''): """ - 'sortname' is used to specify the external sortcode generated by offline spike sorting. - if sortname=='PLX', there should be a ./sort/PLX/*.SortResult file in the tdt block, - which stores the sortcode for every spike; defaults to '', - which uses the original online sort. + Initialize reader for one or multiple TDT data blocks. + + dirname (str, pathlib.Path): + tank-directory of a dataset to be read as multiple segments OR single file of dataset. + In the latter case only the corresponding segment will considered. + sortname (str): + 'sortname' is used to specify the external sortcode generated by offline spike sorting. + if sortname=='PLX', there should be a ./sort/PLX/*.SortResult file in the tdt block, + which stores the sortcode for every spike + Default: '', uses the original online sort. + + """ BaseRawIO.__init__(self) - dirname = str(dirname) - if dirname.endswith('/'): - dirname = dirname[:-1] - self.dirname = dirname + dirname = Path(dirname) + if dirname.is_dir(): + self.dirname = Path(dirname) + self.tdt_block_mode = 'multi' + elif dirname.is_file(): + # in single tdt block mode the dirname also contains the block prefix + self.dirname = dirname.with_suffix('') + self.tdt_block_mode = 'single' + else: + raise ValueError(f'No data folder or file found for {dirname}') self.sortname = sortname def _source_name(self): return self.dirname - def _parse_header(self): - - tankname = os.path.basename(self.dirname) + def _get_filestem(self, segment_name=''): + if self.tdt_block_mode == 'multi': + return self.dirname / segment_name / f'{self.dirname.name}_{segment_name}' + else: + return self.dirname + def _parse_header(self): segment_names = [] - for segment_name in os.listdir(self.dirname): - path = os.path.join(self.dirname, segment_name) - if is_tdtblock(path): - segment_names.append(segment_name) + if self.tdt_block_mode == 'multi': + tankname = self.dirname.stem + for path in self.dirname.iterdir(): + if is_tdtblock(path): + segment_names.append(path.stem) + + # if no block structure was detected, check if current dir contains a set of data + elif is_tdtblock(self.dirname.parent): + segment_names.append(str(self.dirname.stem)) + tankname = None nb_segment = len(segment_names) + if nb_segment == 0: + warnings.warn(f'Could not find any data set belonging to {self.dirname}') # TBK (channel info) info_channel_groups = None for seg_index, segment_name in enumerate(segment_names): - path = os.path.join(self.dirname, segment_name) # TBK contain channels - tbk_filename = os.path.join(path, tankname + '_' + segment_name + '.Tbk') + tbk_filename = self._get_filestem(segment_name).with_suffix('.Tbk') _info_channel_groups = read_tbk(tbk_filename) if info_channel_groups is None: info_channel_groups = _info_channel_groups @@ -81,9 +107,8 @@ # TEV (mixed data) self._tev_datas = [] for seg_index, segment_name in enumerate(segment_names): - path = os.path.join(self.dirname, segment_name) - tev_filename = os.path.join(path, tankname + '_' + segment_name + '.tev') - if os.path.exists(tev_filename): + tev_filename = self._get_filestem(segment_name).with_suffix('.tev') + if tev_filename.exists(): tev_data = np.memmap(tev_filename, mode='r', offset=0, dtype='uint8') else: tev_data = None @@ -94,8 +119,7 @@ self._seg_t_starts = [] self._seg_t_stops = [] for seg_index, segment_name in enumerate(segment_names): - path = os.path.join(self.dirname, segment_name) - tsq_filename = os.path.join(path, tankname + '_' + segment_name + '.tsq') + tsq_filename = self._get_filestem(segment_name).with_suffix('.tsq') tsq = np.fromfile(tsq_filename, dtype=tsq_dtype) self._tsq.append(tsq) # Start and stop times are only found in the second @@ -115,9 +139,13 @@ # (generated after offline sorting) if self.sortname != '': try: - for file in os.listdir(os.path.join(path, 'sort', sortname)): + if self.tdt_block_mode == 'multi': + path = self.dirname + else: + path = self.dirname.parent + for file in os.listdir(path / 'sort' / self.sortname): if file.endswith(".SortResult"): - sortresult_filename = os.path.join(path, 'sort', sortname, file) + sortresult_filename = path / 'sort' / self.sortname / file # get new sortcode newsortcode = np.fromfile(sortresult_filename, 'int8')[ 1024:] # first 1024 bytes are header @@ -181,15 +209,24 @@ assert self._sigs_lengths[seg_index][stream_index] == size # signal start time, relative to start of segment - t_start = data_index['timestamp'][0] + if len(data_index['timestamp']): + t_start = data_index['timestamp'][0] + else: + # if no signal present use segment t_start as dummy value + t_start = self._seg_t_starts[seg_index] if stream_index not in self._sigs_t_start[seg_index]: self._sigs_t_start[seg_index][stream_index] = t_start else: assert self._sigs_t_start[seg_index][stream_index] == t_start # sampling_rate and dtype - _sampling_rate = float(data_index['frequency'][0]) - _dtype = data_formats[data_index['dataformat'][0]] + if len(data_index): + _sampling_rate = float(data_index['frequency'][0]) + _dtype = data_formats[data_index['dataformat'][0]] + else: + # if no signal present use dummy values + _sampling_rate = 1. + _dtype = int if sampling_rate is None: sampling_rate = _sampling_rate dtype = _dtype @@ -202,11 +239,23 @@ assert dtype == _dtype, 'sampling is changing!!!' # data buffer test if SEV file exists otherwise TEV - path = os.path.join(self.dirname, segment_name) - sev_filename = os.path.join(path, tankname + '_' + segment_name + '_' - + info['StoreName'].decode('ascii') - + '_ch' + str(chan_id) + '.sev') - if os.path.exists(sev_filename): + # path = self.dirname / segment_name + if self.tdt_block_mode == 'multi': + # for multi block datasets the names of sev files are fixed + store = info['StoreName'].decode('ascii') + sev_stem = f'{tankname}_{segment_name}_{store}_ch{chan_id}' + sev_filename = (path / sev_stem).with_suffix('.sev') + else: + # for single block datasets the exact name of sev files in not known + sev_regex = f".*_ch{chan_id}.sev" + sev_filename = list(self.dirname.parent.glob(str(sev_regex))) + + # in case non or multiple sev files are found for current stream + channel + if len(sev_filename) != 1: + warnings.warn(f'Could not identify sev file for channel {chan_id}.') + sev_filename = None + + if (sev_filename is not None) and sev_filename.exists(): data = np.memmap(sev_filename, mode='r', offset=0, dtype='uint8') else: data = self._tev_datas[seg_index] @@ -340,7 +389,9 @@ # right border # be careful that bl could be both bl0 and bl1!! border = data.size - (i_stop % sample_per_chunk) - data = data[:-border] + # cut data if not all samples are requested + if border != len(data): + data = data[:-border] if bl == bl0: # left border border = i_start % sample_per_chunk @@ -526,10 +577,10 @@ def is_tdtblock(blockpath): """Is tha path a TDT block (=neo.Segment) ?""" file_ext = list() - if os.path.isdir(blockpath): + if blockpath.is_dir(): # for every file, get extension, convert to lowercase and append - for file in os.listdir(blockpath): - file_ext.append(os.path.splitext(file)[1].lower()) + for file in blockpath.iterdir(): + file_ext.append(file.suffix.lower()) file_ext = set(file_ext) tdt_ext = {'.tbk', '.tdx', '.tev', '.tsq'} diff -Nru neo-0.10.0/neo/test/coretest/tmp.py neo-0.10.2/neo/test/coretest/tmp.py --- neo-0.10.0/neo/test/coretest/tmp.py 2020-12-08 08:02:30.000000000 +0000 +++ neo-0.10.2/neo/test/coretest/tmp.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -from neo.core import AnalogSignal, SpikeTrain, Block -from neo.test.generate_datasets import fake_neo, clone_object -from neo.test.tools import assert_neo_object_is_compliant, assert_same_sub_schema - - -self_nchildren = 2 -blk = fake_neo(Block, seed=0, n=self_nchildren) -self_unit1, self_unit2, self_unit3, self_unit4 = blk.list_units -self_seg1, self_seg2 = blk.segments -self_targobj = self_seg1 -self_seed1 = self_seg1.annotations["seed"] -self_seed2 = self_seg2.annotations["seed"] - -del self_seg1.annotations["i"] -del self_seg2.annotations["i"] -del self_seg1.annotations["j"] -del self_seg2.annotations["j"] - -self_sigarrs1 = self_seg1.analogsignals -self_sigarrs2 = self_seg2.analogsignals -self_irsigs1 = self_seg1.irregularlysampledsignals -self_irsigs2 = self_seg2.irregularlysampledsignals - -self_trains1 = self_seg1.spiketrains -self_trains2 = self_seg2.spiketrains - -self_epcs1 = self_seg1.epochs -self_epcs2 = self_seg2.epochs -self_evts1 = self_seg1.events -self_evts2 = self_seg2.events - -self_sigarrs1a = clone_object(self_sigarrs1, n=2) -self_irsigs1a = clone_object(self_irsigs1) - -self_trains1a = clone_object(self_trains1) - -self_epcs1a = clone_object(self_epcs1) -self_evts1a = clone_object(self_evts1) -seg1a = fake_neo(Block, seed=self_seed1, n=self_nchildren).segments[0] -assert_same_sub_schema(self_seg1, seg1a) -seg1a.annotations.pop("i") # check_creation doesn't expect these -seg1a.annotations.pop("j") # so we delete them -self_check_creation(seg1a) -seg1a.epochs.append(self_epcs2[0]) -seg1a.annotate(seed=self_seed2) -seg1a.merge(self_seg2) -self_check_creation(seg1a) - -assert_same_sub_schema(self_sigarrs1a + self_sigarrs2, seg1a.analogsignals) -assert_same_sub_schema(self_irsigs1a + self_irsigs2, seg1a.irregularlysampledsignals) - -assert_same_sub_schema(self_epcs1 + self_epcs2, seg1a.epochs) -assert_same_sub_schema(self_evts1 + self_evts2, seg1a.events) - -assert_same_sub_schema(self_trains1 + self_trains2, seg1a.spiketrains) diff -Nru neo-0.10.0/neo/test/iotest/test_biocam.py neo-0.10.2/neo/test/iotest/test_biocam.py --- neo-0.10.0/neo/test/iotest/test_biocam.py 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/neo/test/iotest/test_biocam.py 2022-03-08 09:34:47.000000000 +0000 @@ -0,0 +1,22 @@ +""" +Tests of neo.io.BiocamIO +""" + +import unittest + +from neo.io import BiocamIO +from neo.test.iotest.common_io_test import BaseTestIO + + +class TestBiocamIO(BaseTestIO, unittest.TestCase, ): + ioclass = BiocamIO + entities_to_download = [ + 'biocam' + ] + entities_to_test = [ + 'biocam/biocam_hw3.0_fw1.6.brw' + ] + + +if __name__ == "__main__": + unittest.main() diff -Nru neo-0.10.0/neo/test/iotest/test_neuralynxio.py neo-0.10.2/neo/test/iotest/test_neuralynxio.py --- neo-0.10.0/neo/test/iotest/test_neuralynxio.py 2021-07-26 12:48:41.000000000 +0000 +++ neo-0.10.2/neo/test/iotest/test_neuralynxio.py 2022-02-11 14:04:13.000000000 +0000 @@ -178,6 +178,40 @@ block = nio.read_block(signal_group_mode='group-by-same-units') self.assertEqual(len(block.groups), 1) + def test_read_single_file(self): + filename = self.get_local_path( + 'neuralynx/Cheetah_v5.7.4/original_data/CSC1.ncs' + ) + nio = NeuralynxIO(filename=filename, use_cache=False) + block = nio.read_block() + self.assertTrue(len(block.segments[0].analogsignals) > 0) + self.assertTrue((len(block.segments[0].spiketrains)) == 0) + self.assertTrue((len(block.segments[0].events)) == 0) + self.assertTrue((len(block.segments[0].epochs)) == 0) + + def test_exclude_filename(self): + dname = self.get_local_path( + 'neuralynx/Cheetah_v5.7.4/original_data/' + ) + + # exclude a single file + nio = NeuralynxIO(dirname=dname, exclude_filename='CSC1.ncs', use_cache=False) + block = nio.read_block() + self.assertTrue(len(block.segments[0].analogsignals) > 0) + self.assertTrue((len(block.segments[0].spiketrains)) >= 0) + self.assertTrue((len(block.segments[0].events)) >= 0) + self.assertTrue((len(block.segments[0].epochs)) == 0) + + # exclude all ncs files from session + exclude_files = [f'CSC{i}.ncs' for i in range(6)] + nio = NeuralynxIO(dirname=dname, exclude_filename=exclude_files, + use_cache=False) + block = nio.read_block() + self.assertTrue(len(block.segments[0].analogsignals) == 0) + self.assertTrue((len(block.segments[0].spiketrains)) >= 0) + self.assertTrue((len(block.segments[0].events)) >= 0) + self.assertTrue((len(block.segments[0].epochs)) == 0) + class TestPegasus_v211(CommonNeuralynxIOTest, unittest.TestCase): pegasus_version = '2.1.1' diff -Nru neo-0.10.0/neo/test/iotest/test_nixio_fr.py neo-0.10.2/neo/test/iotest/test_nixio_fr.py --- neo-0.10.0/neo/test/iotest/test_nixio_fr.py 2021-07-26 15:44:26.000000000 +0000 +++ neo-0.10.2/neo/test/iotest/test_nixio_fr.py 2021-10-25 07:08:24.000000000 +0000 @@ -112,10 +112,10 @@ sp = SpikeTrain([3, 4, 5]* s, t_stop=10.0) sp.annotations['railway'] = 'hello train' ev = Event(np.arange(0, 30, 10)*pq.Hz, - labels=np.array(['trig0', 'trig1', 'trig2'], dtype='S')) + labels=np.array(['trig0', 'trig1', 'trig2'], dtype='U')) ev.annotations['venue'] = 'hello event' ev2 = Event(np.arange(0, 30, 10) * pq.Hz, - labels=np.array(['trig0', 'trig1', 'trig2'], dtype='S')) + labels=np.array(['trig0', 'trig1', 'trig2'], dtype='U')) ev2.annotations['evven'] = 'hello ev' seg.spiketrains.append(sp) seg.events.append(ev) diff -Nru neo-0.10.0/neo/test/iotest/test_nwbio.py neo-0.10.2/neo/test/iotest/test_nwbio.py --- neo-0.10.0/neo/test/iotest/test_nwbio.py 2021-07-26 15:44:26.000000000 +0000 +++ neo-0.10.2/neo/test/iotest/test_nwbio.py 2022-02-11 14:04:13.000000000 +0000 @@ -63,16 +63,18 @@ for seg in blk.segments: # AnalogSignal objects # 3 Neo AnalogSignals - a = AnalogSignal(np.random.randn(44, num_chan) * pq.nA, + a = AnalogSignal(name='Signal_a %s' % (seg.name), + signal=np.random.randn(44, num_chan) * pq.nA, sampling_rate=10 * pq.kHz, t_start=50 * pq.ms) - b = AnalogSignal(np.random.randn(64, num_chan) * pq.mV, + b = AnalogSignal(name='Signal_b %s' % (seg.name), + signal=np.random.randn(64, num_chan) * pq.mV, sampling_rate=8 * pq.kHz, t_start=40 * pq.ms) - c = AnalogSignal(np.random.randn(33, num_chan) * pq.uA, + c = AnalogSignal(name='Signal_c %s' % (seg.name), + signal=np.random.randn(33, num_chan) * pq.uA, sampling_rate=10 * pq.kHz, t_start=120 * pq.ms) - # 2 Neo IrregularlySampledSignals d = IrregularlySampledSignal(np.arange(7.0) * pq.ms, np.random.randn(7, num_chan) * pq.mV) @@ -83,7 +85,8 @@ # todo: add waveforms # 1 Neo Event - evt = Event(times=np.arange(0, 30, 10) * pq.ms, + evt = Event(name='Event', + times=np.arange(0, 30, 10) * pq.ms, labels=np.array(['ev0', 'ev1', 'ev2'])) # 2 Neo Epochs @@ -228,17 +231,17 @@ nwbfile = pynwb.NWBHDF5IO(test_file_name, mode="r").read() - self.assertIsInstance(nwbfile.acquisition["response"], pynwb.icephys.CurrentClampSeries) - self.assertIsInstance(nwbfile.stimulus["stimulus"], + self.assertIsInstance(nwbfile.acquisition[response.name], pynwb.icephys.CurrentClampSeries) + self.assertIsInstance(nwbfile.stimulus[stimulus.name], pynwb.icephys.CurrentClampStimulusSeries) - self.assertEqual(nwbfile.acquisition["response"].bridge_balance, + self.assertEqual(nwbfile.acquisition[response.name].bridge_balance, response_annotations["nwb:bridge_balance"]) ior = NWBIO(filename=test_file_name, mode='r') retrieved_block = ior.read_all_blocks()[0] - original_response = original_block.segments[0].filter(name="response")[0] - retrieved_response = retrieved_block.segments[0].filter(name="response")[0] + original_response = original_block.segments[0].filter(name=response.name)[0] + retrieved_response = retrieved_block.segments[0].filter(name=response.name)[0] for attr_name in ("name", "units", "sampling_rate", "t_start"): retrieved_attribute = getattr(retrieved_response, attr_name) original_attribute = getattr(original_response, attr_name) diff -Nru neo-0.10.0/neo/test/iotest/test_spikeglxio.py neo-0.10.2/neo/test/iotest/test_spikeglxio.py --- neo-0.10.0/neo/test/iotest/test_spikeglxio.py 2021-06-28 16:41:50.000000000 +0000 +++ neo-0.10.2/neo/test/iotest/test_spikeglxio.py 2022-03-08 09:34:47.000000000 +0000 @@ -14,7 +14,8 @@ 'spikeglx' ] entities_to_test = [ - 'spikeglx/Noise4Sam_g0' + 'spikeglx/Noise4Sam_g0', + 'spikeglx/TEST_20210920_0_g0' ] diff -Nru neo-0.10.0/neo/test/iotest/test_stimfitio.py neo-0.10.2/neo/test/iotest/test_stimfitio.py --- neo-0.10.0/neo/test/iotest/test_stimfitio.py 2021-07-26 12:48:41.000000000 +0000 +++ neo-0.10.2/neo/test/iotest/test_stimfitio.py 2022-03-08 09:34:55.000000000 +0000 @@ -8,9 +8,15 @@ import unittest from neo.io import StimfitIO -from neo.io.stimfitio import HAS_STFIO from neo.test.iotest.common_io_test import BaseTestIO +try: + import stfio +except Exception: + HAS_STFIO = False +else: + HAS_STFIO = True + @unittest.skipIf(sys.version_info[0] > 2, "not Python 3 compatible") @unittest.skipUnless(HAS_STFIO, "requires stfio") diff -Nru neo-0.10.0/neo/test/issue807b.py neo-0.10.2/neo/test/issue807b.py --- neo-0.10.0/neo/test/issue807b.py 2020-12-08 08:02:33.000000000 +0000 +++ neo-0.10.2/neo/test/issue807b.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -import neo -import numpy as np -import quantities as pq - -time = np.array([0, 1, 2]) -val = np.array([2, 3, 2]) -id = np.array(["a", "b", "c"]) -print(time.shape) -print(val.shape) -print(id.shape) -sig0 = neo.AnalogSignal(val, units="mV", sampling_period=1.0 * pq.ms, time_units="ms") -sig0.array_annotate(id=id) diff -Nru neo-0.10.0/neo/test/issue807.py neo-0.10.2/neo/test/issue807.py --- neo-0.10.0/neo/test/issue807.py 2020-12-08 08:02:33.000000000 +0000 +++ neo-0.10.2/neo/test/issue807.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -import neo -import numpy as np - -time = np.array([0, 1, 2]) -val = np.array([2, 3, 2]) -id = np.array(["a", "b", "c"]) -print(time.shape) -print(val.shape) -print(id.shape) -irsig0 = neo.IrregularlySampledSignal(time, val, units="mV", time_units="ms") -irsig0.array_annotate(id=id) diff -Nru neo-0.10.0/neo/test/issue808.py neo-0.10.2/neo/test/issue808.py --- neo-0.10.0/neo/test/issue808.py 2020-12-08 08:02:33.000000000 +0000 +++ neo-0.10.2/neo/test/issue808.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -import quantities as pq -import numpy as np -import neo - -times = np.arange(0, 3) * pq.s -ev = neo.Event(times=times) -new_time = ev.rescale("us") diff -Nru neo-0.10.0/neo/test/rawiotest/test_biocam.py neo-0.10.2/neo/test/rawiotest/test_biocam.py --- neo-0.10.0/neo/test/rawiotest/test_biocam.py 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/neo/test/rawiotest/test_biocam.py 2022-03-08 09:34:47.000000000 +0000 @@ -0,0 +1,24 @@ +""" +Tests of neo.rawio.BiocamRawIO +""" + +import unittest + +from neo.rawio.biocamrawio import BiocamRawIO +from neo.test.rawiotest.common_rawio_test import BaseTestRawIO + + +class TestBiocamRawIO(BaseTestRawIO, unittest.TestCase, ): + rawioclass = BiocamRawIO + + entities_to_download = [ + 'biocam/biocam_hw3.0_fw1.6.brw' + ] + + entities_to_download = [ + 'biocam', + ] + + +if __name__ == "__main__": + unittest.main() diff -Nru neo-0.10.0/neo/test/rawiotest/test_neuralynxrawio.py neo-0.10.2/neo/test/rawiotest/test_neuralynxrawio.py --- neo-0.10.0/neo/test/rawiotest/test_neuralynxrawio.py 2021-06-28 16:41:50.000000000 +0000 +++ neo-0.10.2/neo/test/rawiotest/test_neuralynxrawio.py 2022-02-11 14:04:13.000000000 +0000 @@ -4,7 +4,8 @@ from neo.rawio.neuralynxrawio.neuralynxrawio import NeuralynxRawIO from neo.rawio.neuralynxrawio.nlxheader import NlxHeader -from neo.rawio.neuralynxrawio.ncssections import (NcsSections, NcsSectionsFactory) +from neo.rawio.neuralynxrawio.ncssections import (NcsSection, NcsSections, + NcsSectionsFactory) from neo.test.rawiotest.common_rawio_test import BaseTestRawIO import logging @@ -119,6 +120,35 @@ self.assertEqual(len(rawio.header['signal_channels']), 0) self.assertEqual(len(rawio.header['event_channels']), 0) + def test_exclude_filenames(self): + # exclude single ncs file from session + dname = self.get_local_path('neuralynx/Cheetah_v5.6.3/original_data/') + rawio = NeuralynxRawIO(dirname=dname, exclude_filename='CSC2.ncs') + rawio.parse_header() + + self.assertEqual(rawio._nb_segment, 2) + self.assertEqual(len(rawio.ncs_filenames), 1) + self.assertEqual(len(rawio.nev_filenames), 1) + sigHdrs = rawio.header['signal_channels'] + self.assertEqual(sigHdrs.size, 1) + self.assertEqual(sigHdrs[0][0], 'CSC1') + self.assertEqual(sigHdrs[0][1], '58') + self.assertEqual(len(rawio.header['spike_channels']), 8) + self.assertEqual(len(rawio.header['event_channels']), 2) + + # exclude multiple files from session + rawio = NeuralynxRawIO(dirname=dname, exclude_filename=['Events.nev', 'CSC2.ncs']) + rawio.parse_header() + + self.assertEqual(rawio._nb_segment, 2) + self.assertEqual(len(rawio.ncs_filenames), 1) + self.assertEqual(len(rawio.nev_filenames), 0) + sigHdrs = rawio.header['signal_channels'] + self.assertEqual(sigHdrs.size, 1) + self.assertEqual(sigHdrs[0][0], 'CSC1') + self.assertEqual(sigHdrs[0][1], '58') + self.assertEqual(len(rawio.header['spike_channels']), 8) + self.assertEqual(len(rawio.header['event_channels']), 0) class TestNcsRecordingType(TestNeuralynxRawIO, unittest.TestCase): """ @@ -278,5 +308,42 @@ self.assertTrue(NcsSectionsFactory._verifySectionsStructure(data1, nb1)) +class TestNcsSections(TestNeuralynxRawIO, unittest.TestCase): + """ + Test building NcsBlocks for files of different revisions. + """ + entities_to_test = [] + + def test_equality(self): + ns0 = NcsSections() + ns1 = NcsSections() + + ns0.microsPerSampUsed = 1 + ns1.microsPerSampUsed = 1 + ns0.sampFreqUsed = 300 + ns1.sampFreqUsed = 300 + + self.assertEqual(ns0, ns1) + + # add sections + ns0.sects = [NcsSection(0, 0, 100, 100, 10)] + ns1.sects = [NcsSection(0, 0, 100, 100, 10)] + + self.assertEqual(ns0, ns1) + + # check inequality for different attributes + # different number of sections + ns0.sects.append(NcsSection(0, 0, 100, 100, 10)) + self.assertNotEqual(ns0, ns1) + + # different section attributes + ns0.sects = [NcsSection(0, 0, 200, 200, 10)] + self.assertNotEqual(ns0, ns1) + + # different attributes + ns0.sampFreqUsed = 400 + self.assertNotEqual(ns0, ns1) + + if __name__ == "__main__": unittest.main() diff -Nru neo-0.10.0/neo/test/rawiotest/test_spikeglxrawio.py neo-0.10.2/neo/test/rawiotest/test_spikeglxrawio.py --- neo-0.10.0/neo/test/rawiotest/test_spikeglxrawio.py 2021-06-28 16:41:50.000000000 +0000 +++ neo-0.10.2/neo/test/rawiotest/test_spikeglxrawio.py 2022-03-08 09:34:47.000000000 +0000 @@ -14,9 +14,19 @@ 'spikeglx' ] entities_to_test = [ - 'spikeglx/Noise4Sam_g0' + 'spikeglx/Noise4Sam_g0', + 'spikeglx/TEST_20210920_0_g0' ] + def test_with_location(self): + rawio = SpikeGLXRawIO(self.get_local_path('spikeglx/Noise4Sam_g0'), load_channel_location=True) + rawio.parse_header() + # one of the stream have channel location + have_location = [] + for sig_anotations in rawio.raw_annotations['blocks'][0]['segments'][0]['signals']: + have_location.append('channel_location_0' in sig_anotations['__array_annotations__']) + assert any(have_location) + if __name__ == "__main__": unittest.main() diff -Nru neo-0.10.0/neo/test/rawiotest/test_tdtrawio.py neo-0.10.2/neo/test/rawiotest/test_tdtrawio.py --- neo-0.10.0/neo/test/rawiotest/test_tdtrawio.py 2021-06-28 16:41:50.000000000 +0000 +++ neo-0.10.2/neo/test/rawiotest/test_tdtrawio.py 2022-03-08 09:34:47.000000000 +0000 @@ -1,4 +1,6 @@ import unittest +from pathlib import Path +from numpy.testing import assert_array_equal, assert_ from neo.rawio.tdtrawio import TdtRawIO from neo.test.rawiotest.common_rawio_test import BaseTestRawIO @@ -10,9 +12,49 @@ 'tdt' ] entities_to_test = [ - 'tdt/aep_05' + 'tdt/aep_05', + 'tdt/aep_05/Block-1/aep_05_Block-1.Tdx' ] + def test_invalid_dirname(self): + invalid_name = 'random_non_existant_tdt_filename' + assert not Path(invalid_name).exists() + + with self.assertRaises(ValueError): + TdtRawIO(invalid_name) + + def test_compare_load_multi_single_block(self): + dirname = self.get_local_path('tdt/aep_05') + filename = self.get_local_path('tdt/aep_05/Block-1/aep_05_Block-1.Tdx') + + io_single = TdtRawIO(filename) + io_multi = TdtRawIO(dirname) + + io_single.parse_header() + io_multi.parse_header() + + self.assertEqual(io_single.tdt_block_mode, 'single') + self.assertEqual(io_multi.tdt_block_mode, 'multi') + + self.assertEqual(io_single.block_count(), 1) + self.assertEqual(io_multi.block_count(), 1) + + self.assertEqual(io_single.segment_count(0), 1) + self.assertEqual(io_multi.segment_count(0), 2) + + # compare header infos + assert_array_equal(io_single.header['signal_streams'], io_multi.header['signal_streams']) + assert_array_equal(io_single.header['signal_channels'], io_multi.header['signal_channels']) + assert_array_equal(io_single.header['event_channels'], io_multi.header['event_channels']) + + # not all spiking channels are present in first tdt block (segment) + for spike_channel in io_single.header['spike_channels']: + self.assertIn(spike_channel, io_multi.header['spike_channels']) + + # check that extracted signal chunks are identical + assert_array_equal(io_single.get_analogsignal_chunk(0, 0, 0, 100, 0), + io_multi.get_analogsignal_chunk(0, 0, 0, 100, 0)) + if __name__ == "__main__": unittest.main() diff -Nru neo-0.10.0/neo/test/README.txt neo-0.10.2/neo/test/README.txt --- neo-0.10.0/neo/test/README.txt 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/neo/test/README.txt 2020-08-28 09:11:20.000000000 +0000 @@ -0,0 +1,19 @@ +To run all tests: + + $ python -m unittest discover + +If you have nose installed: + + $ nosetests + + +To run tests from an individual file: + + $ python test_analogsignal.py + +(in all Python versions) + + + +For coverage +nosetests --with-coverage --cover-erase --cover-package=neo diff -Nru neo-0.10.0/neo/version.py neo-0.10.2/neo/version.py --- neo-0.10.0/neo/version.py 2021-07-27 08:39:25.000000000 +0000 +++ neo-0.10.2/neo/version.py 2022-03-08 14:27:41.000000000 +0000 @@ -1 +1 @@ -version = '0.10.0' +version = '0.10.2' diff -Nru neo-0.10.0/neo.egg-info/PKG-INFO neo-0.10.2/neo.egg-info/PKG-INFO --- neo-0.10.0/neo.egg-info/PKG-INFO 2021-07-27 10:22:26.000000000 +0000 +++ neo-0.10.2/neo.egg-info/PKG-INFO 2022-03-08 14:28:37.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: neo -Version: 0.10.0 +Version: 0.10.2 Summary: Neo is a package for representing electrophysiology data in Python, together with support for reading a wide range of neurophysiology file formats Home-page: https://neuralensemble.org/neo Author: Neo authors and contributors @@ -61,7 +61,7 @@ To cite Neo in publications, see CITATION.txt - :copyright: Copyright 2010-2021 by the Neo team, see doc/source/authors.rst. + :copyright: Copyright 2010-2022 by the Neo team, see doc/source/authors.rst. :license: 3-Clause Revised BSD License, see LICENSE.txt for details. Funding @@ -100,9 +100,9 @@ Classifier: Programming Language :: Python :: 3 :: Only Classifier: Topic :: Scientific/Engineering Requires-Python: >=3.7 -Provides-Extra: tiffio -Provides-Extra: nixio +Provides-Extra: igorproio Provides-Extra: kwikio -Provides-Extra: stimfitio Provides-Extra: neomatlabio -Provides-Extra: igorproio +Provides-Extra: nixio +Provides-Extra: stimfitio +Provides-Extra: tiffio diff -Nru neo-0.10.0/neo.egg-info/SOURCES.txt neo-0.10.2/neo.egg-info/SOURCES.txt --- neo-0.10.0/neo.egg-info/SOURCES.txt 2021-07-27 10:22:26.000000000 +0000 +++ neo-0.10.2/neo.egg-info/SOURCES.txt 2022-03-08 14:28:37.000000000 +0000 @@ -1,19 +1,29 @@ +.gitignore +.pep8speaks.yml +.travis.yml +AUTHORS +CITATION.txt +CODE_OF_CONDUCT.md +CONTRIBUTING.md LICENSE.txt MANIFEST.in README.rst +requirements.txt setup.py +tox.ini doc/Makefile doc/make.bat +doc/requirements_docs.txt +doc/requirements_rtd.txt doc/old_stuffs/gif2011workshop.rst doc/old_stuffs/specific_annotations.rst doc/source/api_reference.rst doc/source/authors.rst -doc/source/authors.rst.orig doc/source/conf.py doc/source/core.rst doc/source/developers_guide.rst -doc/source/developers_guide.rst.orig doc/source/examples.rst +doc/source/governance.rst doc/source/grouping.rst doc/source/index.rst doc/source/install.rst @@ -22,19 +32,20 @@ doc/source/rawio.rst doc/source/usecases.rst doc/source/whatisnew.rst -doc/source/images/.DS_Store +doc/source/images/IODiagram.eps +doc/source/images/IODiagram.png doc/source/images/base_schematic.png doc/source/images/generate_diagram.py +doc/source/images/generate_io_overview.py doc/source/images/multi_segment_diagram.png doc/source/images/multi_segment_diagram_spiketrain.png -doc/source/images/neo_UML_French_workshop.png -doc/source/images/neo_ecosystem.png +doc/source/images/neo_ecosystem.drawio doc/source/images/neologo.png doc/source/images/neologo_light.png -doc/source/images/neologo_optical.png doc/source/images/simple_generated_diagram.png doc/source/releases/0.10.0.rst -doc/source/releases/0.10.0.rst.orig +doc/source/releases/0.10.1.rst +doc/source/releases/0.10.2.rst doc/source/releases/0.5.0.rst doc/source/releases/0.5.1.rst doc/source/releases/0.5.2.rst @@ -43,20 +54,19 @@ doc/source/releases/0.7.1.rst doc/source/releases/0.7.2.rst doc/source/releases/0.8.0.rst -doc/source/releases/0.8.0.rst.orig doc/source/releases/0.9.0.rst doc/source/scripts/multi_tetrode_example.py doc/source/scripts/spike_sorting_example.py examples/generated_data.py -examples/hbp_d571_example.py -examples/hbp_d571_example2.py -examples/hbp_d571_example_orig.py +examples/igorio.ipynb examples/imageseq.py examples/read_files_neo_io.py examples/read_files_neo_rawio.py examples/read_proxy_with_lazy_load.py examples/roi_demo.py examples/simple_plot_with_matplotlib.py +examples/nmc-portal/grouped_ephys/B95/B95_Ch0_IDRest_107.ibw +examples/nmc-portal/grouped_ephys/B95/B95_Ch0_IDRest_107.pxp neo/__init__.py neo/version.py neo.egg-info/PKG-INFO @@ -92,6 +102,7 @@ neo/io/basefromrawio.py neo/io/baseio.py neo/io/bci2000io.py +neo/io/biocamio.py neo/io/blackrockio.py neo/io/blkio.py neo/io/brainvisionio.py @@ -120,6 +131,7 @@ neo/io/nixio_fr.py neo/io/nwbio.py neo/io/openephysbinaryio.py +neo/io/openephysbinaryio_old.py neo/io/openephysio.py neo/io/phyio.py neo/io/pickleio.py @@ -142,6 +154,7 @@ neo/rawio/axonrawio.py neo/rawio/baserawio.py neo/rawio/bci2000rawio.py +neo/rawio/biocamrawio.py neo/rawio/blackrockrawio.py neo/rawio/brainvisionrawio.py neo/rawio/cedrawio.py @@ -170,11 +183,9 @@ neo/rawio/neuralynxrawio/ncssections.py neo/rawio/neuralynxrawio/neuralynxrawio.py neo/rawio/neuralynxrawio/nlxheader.py +neo/test/README.txt neo/test/__init__.py neo/test/generate_datasets.py -neo/test/issue807.py -neo/test/issue807b.py -neo/test/issue808.py neo/test/tools.py neo/test/coretest/__init__.py neo/test/coretest/test_analogsignal.py @@ -193,7 +204,6 @@ neo/test/coretest/test_spiketrain.py neo/test/coretest/test_spiketrainlist.py neo/test/coretest/test_view.py -neo/test/coretest/tmp.py neo/test/iotest/__init__.py neo/test/iotest/common_io_test.py neo/test/iotest/test_alphaomegaio.py @@ -205,6 +215,7 @@ neo/test/iotest/test_axonio.py neo/test/iotest/test_baseio.py neo/test/iotest/test_bci2000.py +neo/test/iotest/test_biocam.py neo/test/iotest/test_blackrockio.py neo/test/iotest/test_brainvisionio.py neo/test/iotest/test_brainwaredamio.py @@ -254,6 +265,7 @@ neo/test/rawiotest/test_axonarawio.py neo/test/rawiotest/test_axonrawio.py neo/test/rawiotest/test_bci2000rawio.py +neo/test/rawiotest/test_biocam.py neo/test/rawiotest/test_blackrockrawio.py neo/test/rawiotest/test_brainvisionrawio.py neo/test/rawiotest/test_cedrawio.py diff -Nru neo-0.10.0/.pep8speaks.yml neo-0.10.2/.pep8speaks.yml --- neo-0.10.0/.pep8speaks.yml 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/.pep8speaks.yml 2020-12-14 14:21:55.000000000 +0000 @@ -0,0 +1,6 @@ +pycodestyle: + max-line-length: 99 # Default is 79 in PEP8 + ignore: + - W503 # Change in PEP8, this warning is replaced by W504 + - E127 + - E128 diff -Nru neo-0.10.0/PKG-INFO neo-0.10.2/PKG-INFO --- neo-0.10.0/PKG-INFO 2021-07-27 10:22:26.000000000 +0000 +++ neo-0.10.2/PKG-INFO 2022-03-08 14:28:37.558800500 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: neo -Version: 0.10.0 +Version: 0.10.2 Summary: Neo is a package for representing electrophysiology data in Python, together with support for reading a wide range of neurophysiology file formats Home-page: https://neuralensemble.org/neo Author: Neo authors and contributors @@ -61,7 +61,7 @@ To cite Neo in publications, see CITATION.txt - :copyright: Copyright 2010-2021 by the Neo team, see doc/source/authors.rst. + :copyright: Copyright 2010-2022 by the Neo team, see doc/source/authors.rst. :license: 3-Clause Revised BSD License, see LICENSE.txt for details. Funding @@ -100,9 +100,9 @@ Classifier: Programming Language :: Python :: 3 :: Only Classifier: Topic :: Scientific/Engineering Requires-Python: >=3.7 -Provides-Extra: tiffio -Provides-Extra: nixio +Provides-Extra: igorproio Provides-Extra: kwikio -Provides-Extra: stimfitio Provides-Extra: neomatlabio -Provides-Extra: igorproio +Provides-Extra: nixio +Provides-Extra: stimfitio +Provides-Extra: tiffio diff -Nru neo-0.10.0/README.rst neo-0.10.2/README.rst --- neo-0.10.0/README.rst 2021-07-27 08:39:25.000000000 +0000 +++ neo-0.10.2/README.rst 2022-03-08 09:34:55.000000000 +0000 @@ -53,7 +53,7 @@ To cite Neo in publications, see CITATION.txt -:copyright: Copyright 2010-2021 by the Neo team, see doc/source/authors.rst. +:copyright: Copyright 2010-2022 by the Neo team, see doc/source/authors.rst. :license: 3-Clause Revised BSD License, see LICENSE.txt for details. Funding diff -Nru neo-0.10.0/requirements.txt neo-0.10.2/requirements.txt --- neo-0.10.0/requirements.txt 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/requirements.txt 2021-08-23 13:37:43.000000000 +0000 @@ -0,0 +1,2 @@ +numpy>=1.16.1 +quantities>=0.12.1 diff -Nru neo-0.10.0/tox.ini neo-0.10.2/tox.ini --- neo-0.10.0/tox.ini 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/tox.ini 2020-08-28 09:11:20.000000000 +0000 @@ -0,0 +1,10 @@ +[tox] +envlist = py35, py36, py37 +[testenv] +commands=nosetests {posargs} +deps = + # essential + numpy>=1.7.1,!=1.16.0 + quantities>=0.9.0 + # for running tests + nose>=1.1.2 diff -Nru neo-0.10.0/.travis.yml neo-0.10.2/.travis.yml --- neo-0.10.0/.travis.yml 1970-01-01 00:00:00.000000000 +0000 +++ neo-0.10.2/.travis.yml 2021-08-23 13:37:43.000000000 +0000 @@ -0,0 +1,47 @@ +language: python +dist: xenial +sudo: false + +matrix: + include: + - python: "3.7" + env: NUMPY_VERSION="1.16.6" + - python: "3.7" + env: NUMPY_VERSION="1.21.0" + - python: "3.8" + env: NUMPY_VERSION="1.16.6" + - python: "3.8" + env: NUMPY_VERSION="1.17.5" + - python: "3.8" + env: NUMPY_VERSION="1.18.5" + - python: "3.8" + env: NUMPY_VERSION="1.19.5" + - python: "3.8" + env: NUMPY_VERSION="1.20.3" + - python: "3.8" + env: NUMPY_VERSION="1.21.0" + - python: "3.9" + env: NUMPY_VERSION="1.16.6" + - python: "3.9" + env: NUMPY_VERSION="1.17.5" + - python: "3.9" + env: NUMPY_VERSION="1.18.5" + - python: "3.9" + env: NUMPY_VERSION="1.19.5" + - python: "3.9" + env: NUMPY_VERSION="1.20.3" + - python: "3.9" + env: NUMPY_VERSION="1.21.0" + +# command to install dependencies +before_install: + - pip install "numpy==$NUMPY_VERSION" +install: + - pip install -r requirements.txt + - pip install nose + - pip install coveralls + - pip install . + - pip install pillow +# command to run tests, e.g. python setup.py test +script: + nosetests --with-coverage --cover-package=neo