diff --git a/doc/neuroml_logo.png b/doc/_static/neuroml_logo.png similarity index 100% rename from doc/neuroml_logo.png rename to doc/_static/neuroml_logo.png diff --git a/doc/api.rst b/doc/api.rst new file mode 100644 index 00000000..54487358 --- /dev/null +++ b/doc/api.rst @@ -0,0 +1,13 @@ +API documentation +================= + +.. toctree:: + :maxdepth: 2 + + coreclasses + loaders + writers + utils + arraymorph + + diff --git a/doc/arraymorph.rst b/doc/arraymorph.rst new file mode 100644 index 00000000..243300eb --- /dev/null +++ b/doc/arraymorph.rst @@ -0,0 +1,10 @@ + +:mod:`arraymorph` Module +------------------------ + +.. automodule:: neuroml.arraymorph + :members: + :undoc-members: + :show-inheritance: + + diff --git a/doc/bibliography.rst b/doc/bibliography.rst new file mode 100644 index 00000000..2e03d015 --- /dev/null +++ b/doc/bibliography.rst @@ -0,0 +1,5 @@ +References +========== + +.. bibliography:: + :all: diff --git a/doc/conf.py b/doc/conf.py index c43cabf1..da0c6f79 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -11,7 +11,8 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import sys +import os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -28,13 +29,19 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', + 'sphinxcontrib.bibtex'] + +bibtex_bibfiles = ['refs.bib'] + +# Include TODOs in docs +todo_include_todos = True # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. -source_suffix = '.txt' +source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' @@ -44,16 +51,19 @@ # General information about the project. project = u'libNeuroML' -copyright = u'2017, libNeuroML authors and contributors' +copyright = u'2021, libNeuroML authors and contributors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -for l in open('../neuroml/__init__.py'): - if '__version__' in l: - version = l.split("'")[1] +version = "" +for aline in open('../neuroml/__init__.py'): + # space here is important since __version__ is used in generation of + # version_info also + if '__version__ =' in aline: + version = aline.split("'")[1] # The full version, including alpha/beta/rc tags. release = version @@ -115,7 +125,7 @@ # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = 'neuroml_logo.png' +html_logo = '_static/neuroml_logo.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -174,7 +184,6 @@ # -- Options for LaTeX output -------------------------------------------------- -latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', @@ -183,13 +192,13 @@ # Additional stuff for the LaTeX preamble. #'preamble': '', -} +latex_elements = {} # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'libNeuroML.tex', u'libNeuroML Documentation', - u'libNeuroML authors and contributors', 'manual'), + ('index', 'libNeuroML.tex', 'libNeuroML Documentation', + 'libNeuroML authors and contributors', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -218,8 +227,8 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'libneuroml', u'libNeuroML Documentation', - [u'libNeuroML authors and contributors'], 1) + ('index', 'libneuroml', 'libNeuroML Documentation', + ['libNeuroML authors and contributors'], 1) ] # If true, show URL addresses after external links. @@ -232,9 +241,9 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'libNeuroML', u'libNeuroML Documentation', - u'libNeuroML authors and contributors', 'libNeuroML', 'One line description of project.', - 'Miscellaneous'), + ('index', 'libNeuroML', 'libNeuroML Documentation', + 'libNeuroML authors and contributors', 'libNeuroML', 'This package provides libNeuroML for working with neuronal models specified in NeuroML 2.', + 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. diff --git a/doc/neuroml.nml.txt b/doc/coreclasses.rst similarity index 65% rename from doc/neuroml.nml.txt rename to doc/coreclasses.rst index 81235127..6abbdd86 100644 --- a/doc/neuroml.nml.txt +++ b/doc/coreclasses.rst @@ -1,10 +1,5 @@ -NeuroML core classes -==================== - - - -:mod:`nml` Module ------------------------------ +:mod:`nml` Module (NeuroML Core classes) +----------------------------------------- Note: This module is included in the top level of the `neuroml` package, so you can use these classes by importing neuroml: @@ -14,5 +9,6 @@ Note: This module is included in the top level of the `neuroml` package, so you .. automodule:: neuroml.nml.nml :members: - :show-inheritance: + + diff --git a/doc/examples.txt b/doc/examples.rst similarity index 100% rename from doc/examples.txt rename to doc/examples.rst diff --git a/doc/how_to_contribute.rst b/doc/how_to_contribute.rst new file mode 100644 index 00000000..a7b72d7c --- /dev/null +++ b/doc/how_to_contribute.rst @@ -0,0 +1,113 @@ +How to contribute +================= + +libNeuroML development happens on GitHub, so you will need a GitHub account to contribute to the repository. +Contributions are made using the standard `Pull Request`_ workflow. + +Setting up +---------- + +Please take a look at the GitHub documentation here: http://help.github.com/fork-a-repo/ + +To begin, please fork the repo on the GitHub website. +You should now have a libNeuroML under you username. +Next, we clone our fork to get a local copy on our computer: + +:: + + git clone git@github.com:_username_/libNeuroML.git + +While not necessary, it is good practice to add the upstream repository as a remote that you will follow: + +:: + + cd libNeuroML + git remote add upstream https://github.com/NeuralEnsemble/libNeuroML.git + git fetch upstream + + +You can check which branch are you following doing: + +:: + + git branch -a + +You should have something like: + +:: + + git branch -a + * master + remotes/origin/HEAD -> origin/master + remotes/origin/master + remotes/upstream/master + + +Sync with upstream +------------------ + +Before starting to do some work, please check to see that you have the latest copy of the sources in your local repository: + +:: + + git fetch upstream + git checkout development + git merge upstream/development + +Working locally on a dedicated branch +------------------------------------- + +Now that we have a fork, we can start making our changes to the source code. +The best way to do it is to create a branch with a descriptive name to indicate what are you working on. +Generally, your will branch off from the upstream `development` branch, which will contain the latest code. + +For example, just for the sake of this guide, I'm going to work on issue #2. + +:: + + git checkout development + git checkout -b fix-2 + + +We can work in this branch, and make as many commits as we need to: + +:: + + # hack hack hack + git commit -am "some decent commit message here" + + +Once we have finished working, we can push the branch online to our fork: + +:: + + git push origin fix-2 + + +We can then open a pull-request to merge our ``fix-2`` branch into ``upstream/development``. +If your code is not ready to be included, you can update the code on your branch and any more commits you add there will be added to the Pull Request. +Members of the libNeuroML development team will then discuss your changes with you, perhaps suggest tweaks, and then merge it when ready. + +Continuous integration +----------------------- + +libNeuroML uses continuous integration (`Wikipedia `_). +Each commit to the master or development branches is tested, along with all commits to pull requests. +The latest status of the continuous integration tests can be seen `here on GitHub Actions `_. + +Release process +--------------- + +libNeuroML is part of the official NeuroML release cycle. +When a new libNeuroML release is ready the following needs to happen: + +- Update version number in setup.py +- update version number in doc/conf.py +- update release number in doc/conf.py (same as version number) +- update changelog in README.md +- merge development branch with master (This should happen via pull request - do not do the merge yourself even if you are an owner of the repository. +- push latest release to PyPi + +More information on the NeuroML release process can be found on the `NeuroML documentation page `_. + +.. _Pull Request: http://help.github.com/send-pull-requests/ diff --git a/doc/how_to_contribute.txt b/doc/how_to_contribute.txt deleted file mode 100644 index c16c8b7c..00000000 --- a/doc/how_to_contribute.txt +++ /dev/null @@ -1,169 +0,0 @@ -How to contribute -================= - -To contribute to libNeuroML you need a github account then you should -fork the repository at https://github.com/NeuralEnsemble/libNeuroML - -Note: Fork is not a bad thing on a Github workflow. Fork basically -means you have your own repository which is connected with upstream -(the main repository from which official releases will be made). You -can contribute back to upstream using `Pull Request`_ - -Setting up ----------- - -Have a quick view at the doc: http://help.github.com/fork-a-repo/ - -1. Fork the repo (done on github website). - Now you should have a libNeuroML under you username (mine for example sits - happily here: https://github.com/mattions/libNeuroML) - -2. Clone your repo locally (This is done once!) - -:: - - git clone git@github.com:_username_/libNeuroML.git - -3. Add upstream as remote branch which you follow - -:: - - cd libNeuroML - git remote add upstream https://github.com/NeuralEnsemble/libNeuroML.git - git fetch upstream - -You can check which branch are you following doing: - -:: - - git branch -a - -you should have something like: - -:: - - mattions@triton:libNeuroML(master*)$ git branch -a - * master - remotes/origin/HEAD -> origin/master - remotes/origin/master - remotes/upstream/master - -This means you are currently on branch master and there are two remotes -branches ``origin/master`` which is your origin master (the branch where -you master gets pushed automatically and ``upstream/master`` which is -the upstream master (the NeuroEnsemble one). - -Sync with upstream ------------------- - -Before starting to do some work, I’ll suggest to get the latest -development going on the upstream repo - -:: - - git fetch upstream - git merge upstream/master - -If there are no conflict, you are all set, if there are some you can -solve them with - -:: - - git mergetool - -which will fire up your favourite merger to do a 3-ways merge. - -3-ways means you will have your *local* file on your left, the *remote* -file on your right, and the file in the middle is the conflicted one, -which you need to solve. - -A nice 3-ways merger makes this process very easy, and merging could be -fun. To see what you have currently installed just do ``git mergetool`` - -This is my response - -:: - - mattions@triton:libNeuroML(master*)$ git mergetool - merge tool candidates: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis bc3 emerge vimdiff - No files need merging - -[Meld] (http://meldmerge.org/) is the first of the list and would be -automatically picked up by ``git mergetool``. Chose your favourite. - -Well done, now you are all set to do some cool work! - -Working locally on a dedicated branch -------------------------------------- - -Now you can work on your repo. The best way to do it is to create a -branch with a descriptive name which indicate what are you working on. - -For example, just for the sake of this guide, I’m going to close `#2`_ - -:: - - git checkout -b fix-2 - -Now, I’m working on a different branch from master which is fix-2 This -will come handy in a minute. - -:: - - hack hack hack - git commit -am "some decent commit message here" - -Now that I found how to fix this issue, I just want to push my branch -online and open a pull request. - -1. Push the branch online - - :: - - git push origin fix-2 - -2. Open the pull request - -Here I want to open a pull-request to integrate ``fix-2`` into -``upstream/master`` - -To do that I click Pull-Request and automatically a new Issue `#3`_ is -created where it is possible to comment. - -If your code is not ready to be include, you can update the code on your -branch and automatically the Pull Request will sync to the latest -commit, so it is possible to change it after the Pull Request is -started. Don’t be scare to open one. - -Release process ---------------- -libNeuroML is part of the official NeuroML release cycle. As of -1/09/13 we are still ironing out the proecure. When a new libNueroML -release is ready the following needs to happen: - - Update version number in setup.py - - update version number in doc/conf.py - - update release number in doc/conf.py (same as version number) - - update changelog in README.md - - merge development branch with master (This should happen via pull - request - do not do the merge yourself even if you are an owner - of the repository. - - push latest release to PyPi - -Miscellaneous -------------- - -- `Nice guide about git`_ - -- `Quick reference for git`_ - -- Remember to `tell git your name`_, so we know who contributes! - -- Always known in which branch you are using this `bash function`_ - -.. _Pull Request: http://help.github.com/send-pull-requests/ -.. _#2: https://github.com/NeuralEnsemble/libNeuroML/issues/2 -.. _#3: https://github.com/NeuralEnsemble/libNeuroML/issues/3 -.. _Nice guide about git: http://rogerdudler.github.com/git-guide/ -.. _tell git your name: http://help.github.com/set-your-user-name-email-and-github-token/ -.. _bash function: https://gist.github.com/2051095 -.. _Quick reference for git: http://gitref.org/ diff --git a/doc/implementation_of_bindings.txt b/doc/implementation_of_bindings.rst similarity index 100% rename from doc/implementation_of_bindings.txt rename to doc/implementation_of_bindings.rst diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 00000000..2086e01a --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,53 @@ +libNeuroML: documentation +========================== + +Welcome to the libNeuroML documentation. +Here you will find information on installing, using, and contributing to libNeuroML. +For more information on NeuroML standard, other tools in the NeuroML eco-system, the NeuroML community and how to get in touch with us, please see the documentation at https://docs.neuroml.org. + + +User documentation +************************ + +.. toctree:: + :maxdepth: 2 + + introduction + install + api + examples + bibliography + + +Developer documentation +************************ + +.. toctree:: + :maxdepth: 2 + + how_to_contribute + implementation_of_bindings + +Events and meetings +************************ + +.. toctree:: + :maxdepth: 1 + + meeting_june_2012 + +Miscellaneous +************************ + +.. toctree:: + :maxdepth: 1 + + nodes_segments_sections + + +Indices and tables +******************* + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/doc/index.txt b/doc/index.txt deleted file mode 100644 index 923ae6ba..00000000 --- a/doc/index.txt +++ /dev/null @@ -1,39 +0,0 @@ -======================== -libNeuroML: documentation -======================== - -.. toctree:: - :maxdepth: 2 - - introduction - install - examples - tools - -======================= -Developer documentation -======================= - -.. toctree:: - :maxdepth: 2 - - how_to_contribute - implementation_of_bindings - -.. Source documentation - ================== - - .. toctree:: - :maxdepth: 3 - -modules - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - - - diff --git a/doc/install.rst b/doc/install.rst new file mode 100644 index 00000000..3a1b2085 --- /dev/null +++ b/doc/install.rst @@ -0,0 +1,111 @@ +Installation +============ + +Using Pip +---------- + +On most systems with a Python installation, libNeuroML can be installed using the default Python package manager, Pip: + +:: + + pip install libNeuroML + +It is recommended to use a `virtual environment `_ when installing Python packages using `pip` to prevent these from conflicting with other system libraries. + +This will support the default XML serialization. +To install all of requirements to include the other serialisations, use + +:: + + # On Ubuntu based systems + sudo apt-get install libhdf5-dev + pip install libNeuroML[full] + +The ``apt`` line is required at time of writing because PyTables' wheels for python 3.7 depend on the system libhdf5. + + +On Fedora based systems +------------------------ + +On `Fedora `_ Linux systems, the `NeuroFedora `_ community provides libNeuroML in the `standard Fedora repos `_ and can be installed using the following commands: + +:: + + sudo dnf install python3-libNeuroML + + +Install from source +-------------------- + +You can clone the `GitHub repository `_ and also build libNeuroML from the sources. +For this, you will need `git`_: + +:: + + git clone git://github.com/NeuralEnsemble/libNeuroML.git + cd libNeuroML + + +More details about the git repository and making your own branch/fork are `here `_. +To build and install libNeuroML, you can use the standard install method for Python packages (preferably in a virtual environment): + +:: + + python setup.py install + +To use the **latest development version of libNeuroML**, switch to the development branch: + +:: + + git checkout development + sudo python setup.py install + + +Run an example +-------------- + +Some sample scripts are included in `neuroml/examples`, e.g. : + +:: + + cd neuroml/examples + python build_network.py + +The standard examples can also be found :doc:`examples`. + +Unit tests +---------- + +To run unit tests cd to the directory `neuroml/test` and use the Python unittest module discover method: + +:: + + cd neuroml/test/ + python -m unittest discover + +If all tests passed correctly, your output should look something like this: + +:: + + ....... + ---------------------------------------------------------------------- + Ran 55 tests in 40.1s + + OK + +You can also use PyTest to run tests. + +:: + + pip install pytest + pytest -v --strict -W all + + +To ignore some tests, like the MongoDB test which requires a MongoDB setup, run: + +:: + + pytest -v -k "not mongodb" --strict -W all + + +.. _Git: https://git-scm.com diff --git a/doc/install.txt b/doc/install.txt deleted file mode 100644 index 0c332972..00000000 --- a/doc/install.txt +++ /dev/null @@ -1,132 +0,0 @@ -Installation -============ - - -Requirements ----------------------------------------- - - -For the default XML serialization (saving NeuroML to XML files), only *lxml* is required: - -:: - - sudo pip install lxml - -Alternatively, on Linux you can use: - -:: - - sudo apt-get install python-lxml - -To use the other serializations (e.g. HDF5, JSON, see `Vella et al. 2014 `_) -the following will also be required: - -:: - - sudo apt-get install libhdf5-serial-dev - sudo pip install numpy - sudo pip install numexpr - sudo pip install jsonpickle - sudo pip install pymongo - sudo pip install simplejson - sudo pip install tables - -See `.travis.yml `_ for the latest requirements on libraries etc. - -Install libNeuroML via pip ----------------------------------------- - -:: - - pip install libNeuroML - -This is always the latest stable branch from GitHub, and installs the minimal requirements (``lxml``). - -To install all of requirements to include the other serialisations, use - -:: - - sudo apt-get install libhdf5-dev - pip install libNeuroML[full] - -The ``apt`` line is required at time of writing because PyTables' wheels for python 3.7 depend on the system libhdf5. - - - - -Install using a local copy of libNeuroML source ------------------------------------------------ - -Install `git`_ and type: - -:: - - git clone git://github.com/NeuralEnsemble/libNeuroML.git - cd libNeuroML - - -More details about the git repository and making your own branch/fork are `here `_. - - -.. _Git: http://rogerdudler.github.com/git-guide/ - - -Use the standard install method for Python packages: - - -:: - - sudo python setup.py install - -To use the **latest development version of libNeuroML**, switch to the development branch: - - -:: - - git checkout development - sudo python setup.py install - - -Run an example --------------- - -Some sample scripts are included in `neuroml/examples`, e.g. : - -:: - - cd neuroml/examples - python build_network.py - -The standard examples can also be found `here `_ - -Unit tests ----------- - -To run unit tests cd to the directory '/neuoroml/test' and use the python unittest module discover method: - -:: - - python -m unittest discover - -If everything worked your output should look something like this: - -:: - - ....... - ---------------------------------------------------------------------- - Ran 55 tests in 40.1s - - OK - -Alternatively install and use pytest: - -:: - - pytest -v --strict -W all - - -To ignore some tests, like the mongodb test which requres a mongodb setup, run: - -:: - - pytest -v -k "not mongodb" --strict -W all diff --git a/doc/introduction.rst b/doc/introduction.rst new file mode 100644 index 00000000..303a592f --- /dev/null +++ b/doc/introduction.rst @@ -0,0 +1,33 @@ +Introduction +============ + +This package provides Python libNeuroML, for working with neuronal models specified in `NeuroML 2 `_. + +.. warning:: **libNeuroML targets NeuroML v2.0** + + libNeuroML targets `NeuroML v2.0`_, which is described in `Cannon et al, 2014 `_). + NeuroML v1.8.1 (`Gleeson et al. 2010 `_) is now deprecated and not supported by libNeuroML. + +For a detailed description of libNeuroML see :cite:t:`Vella2014`. +*Please cite the paper if you use libNeuroML.* + +NeuroML +------- + +NeuroML provides an object model for describing neuronal morphologies, ion channels, synapses and 3D network structure. +For more information on NeuroML 2 and LEMS please see the `NeuroML documentation `_. + + +Serialisations +-------------- + +The XML serialisation will be the "natural" serialisation and will follow closely the NeuroML object model. +The format of the XML will be specified by the XML Schema definition (XSD file). + +Other serialisations have been developed (HDF5, JSON, SWC). +Please see :cite:t:`Vella2014` for more details. + + +.. _NeuroML v2.0: http://docs.neuroml.org +.. _LEMS: http://lems.github.io/LEMS/ +.. _NeuroHDF: http://neurohdf.readthedocs.org/en/latest/ diff --git a/doc/introduction.txt b/doc/introduction.txt deleted file mode 100644 index ebd1363e..00000000 --- a/doc/introduction.txt +++ /dev/null @@ -1,47 +0,0 @@ -Introduction -============ - -This package provides Python libNeuroML, for working with neuronal models specified in `NeuroML 2 `_. - -NOTE: libNeuroML targets `NeuroML v2.0`_ (described in -`Cannon et al, 2014 `_) not NeuroML v1.8.1 -(`Gleeson et al. 2010 `_). - -For a detailed description of libNeuroML see: - -| Michael Vella, Robert C. Cannon, Sharon Crook, Andrew P. Davison, Gautham Ganapathy, Hugh P. C. Robinson, R. Angus Silver and Padraig Gleeson -| **libNeuroML and PyLEMS: using Python to combine procedural and declarative modeling approaches in computational neuroscience** -| `Frontiers in Neuroinformatics 2014 `_, doi: 10.3389/fninf.2014.00038 - -**PLEASE CITE THE PAPER ABOVE IF YOU USE libNeuroML!** - -NeuroML -------- - -NeuroML provides an object model for describing neuronal morphologies, ion channels, synapses and 3D network structure. - -Any dynamical components (channels, synapses, abstract cell models) in `NeuroML v2.0`_ will have a definition "behind the scenes" in `LEMS`_. -However, all NeuroML files specify is that "element segment will contain element distal with attributes x, y, z, -diameter..." or "element izhikevichCell will have attributes a, b, c...". - -For more on NeuroML 2 and LEMS see `here `_. - - -Serialisations --------------- - -The XML serialisation will be the "natural" serialisation and will follow closely the NeuroML -object model. The format of the XML will be specified by the XML Schema definition (XSD file). Note: -LEMS definitions of NeuroML ComponentTypes (defining what izhikevichCell does with a, b, c...) -and this XSD file (only saying the izhikevichCell element requires a, b, c...) are currently manually kept in line. - -Other serialisations have been developed (HDF5, JSON, SWC). See -`Vella et al. 2014 `_ for more details. - - - - -.. _NeuroML v2.0: http://www.neuroml.org/neuromlv2 -.. _LEMS: http://lems.github.io/LEMS/ -.. _NeuroHDF: http://neurohdf.readthedocs.org/en/latest/ - diff --git a/doc/loaders.rst b/doc/loaders.rst new file mode 100644 index 00000000..e61a3dfd --- /dev/null +++ b/doc/loaders.rst @@ -0,0 +1,9 @@ +:mod:`loaders` Module +--------------------- + +.. automodule:: neuroml.loaders + :members: + :undoc-members: + :show-inheritance: + + diff --git a/doc/meeting_june_2012.txt b/doc/meeting_june_2012.rst similarity index 98% rename from doc/meeting_june_2012.txt rename to doc/meeting_june_2012.rst index a5d204c2..b00aacc3 100644 --- a/doc/meeting_june_2012.txt +++ b/doc/meeting_june_2012.rst @@ -18,10 +18,6 @@ Minutes Agreeing on terminology (segments, etc.) & scope ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -An introduction to the background to the project and the projected scope is here: - -:doc:`scope_of_project` - A discussion on the definitions of the key terms Node, Segment and Section is here, and was the basis for discussions on these definitions at the meeting: @@ -193,4 +189,4 @@ to interact with simulators is currently termed "Pyramidal", but this will event http://neuralensemble.org/trac/PyNN http://www.neuroml.org/NeuroML2CoreTypes/PyNN.html -http://www.neuroml.org/pynn.php \ No newline at end of file +http://www.neuroml.org/pynn.php diff --git a/doc/modules.txt b/doc/modules.txt deleted file mode 100644 index a7bf4efa..00000000 --- a/doc/modules.txt +++ /dev/null @@ -1,7 +0,0 @@ -neuroml -======= - -.. toctree:: - :maxdepth: 4 - - neuroml diff --git a/doc/neuroml.test.txt b/doc/neuroml.test.txt deleted file mode 100644 index a8f06585..00000000 --- a/doc/neuroml.test.txt +++ /dev/null @@ -1,11 +0,0 @@ -test Package -============ - -:mod:`test_segment` Module --------------------------- - -.. automodule:: neuroml.test.test_segment - :members: - :undoc-members: - :show-inheritance: - diff --git a/doc/neuroml.txt b/doc/neuroml.txt deleted file mode 100644 index 5baf1d17..00000000 --- a/doc/neuroml.txt +++ /dev/null @@ -1,50 +0,0 @@ -neuroml Package -=============== - -:mod:`neuroml` Package ----------------------- - -.. automodule:: neuroml.__init__ - :members: - :undoc-members: - :show-inheritance: - -:mod:`loaders` Module ---------------------- - -.. automodule:: neuroml.loaders - :members: - :undoc-members: - :show-inheritance: - -:mod:`writers` Module ---------------------- - -.. automodule:: neuroml.writers - :members: - :undoc-members: - :show-inheritance: - -:mod:`utils` Module ---------------------- - -.. automodule:: neuroml.utils - :members: - :undoc-members: - :show-inheritance: - -:mod:`arraymorph` Module ------------------------- - -.. automodule:: neuroml.arraymorph - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - - neuroml.nml - diff --git a/doc/nodes_segments_sections.txt b/doc/nodes_segments_sections.rst similarity index 100% rename from doc/nodes_segments_sections.txt rename to doc/nodes_segments_sections.rst diff --git a/doc/note_on_arraymorph.txt b/doc/note_on_arraymorph.txt deleted file mode 100644 index a9f02f9c..00000000 --- a/doc/note_on_arraymorph.txt +++ /dev/null @@ -1,9 +0,0 @@ -Appendix I: Arraymorph -====================== - -Why arraymorph is needed ------------------------- - -How arraymorph works --------------------- - diff --git a/doc/refs.bib b/doc/refs.bib new file mode 100644 index 00000000..0eba5e03 --- /dev/null +++ b/doc/refs.bib @@ -0,0 +1,23 @@ +@Article{Vella2014, + author = {Vella, Michael and Cannon, Robert C. and Crook, Sharon and Davison, Andrew P. and Ganapathy, Gautham and Robinson, Hugh P. C. and Silver, R. Angus and Gleeson, Padraig}, + title = {libNeuroML and PyLEMS: using Python to combine procedural and declarative modeling approaches in computational neuroscience.}, + doi = {10.3389/fninf.2014.00038}, + issn = {1662-5196}, + pages = {38}, + volume = {8}, + abstract = {NeuroML is an XML-based model description language, which provides a powerful common data format for defining and exchanging models of neurons and neuronal networks. In the latest version of NeuroML, the structure and behavior of ion channel, synapse, cell, and network model descriptions are based on underlying definitions provided in LEMS, a domain-independent language for expressing hierarchical mathematical models of physical entities. While declarative approaches for describing models have led to greater exchange of model elements among software tools in computational neuroscience, a frequent criticism of XML-based languages is that they are difficult to work with directly. Here we describe two Application Programming Interfaces (APIs) written in Python (http://www.python.org), which simplify the process of developing and modifying models expressed in NeuroML and LEMS. The libNeuroML API provides a Python object model with a direct mapping to all NeuroML concepts defined by the NeuroML Schema, which facilitates reading and writing the XML equivalents. In addition, it offers a memory-efficient, array-based internal representation, which is useful for handling large-scale connectomics data. The libNeuroML API also includes support for performing common operations that are required when working with NeuroML documents. Access to the LEMS data model is provided by the PyLEMS API, which provides a Python implementation of the LEMS language, including the ability to simulate most models expressed in LEMS. Together, libNeuroML and PyLEMS provide a comprehensive solution for interacting with NeuroML models in a Python environment.}, + country = {Switzerland}, + issn-linking = {1662-5196}, + journal = {Frontiers in neuroinformatics}, + keywords = {API; LEMS; NeuroML; Python; SWC; model specification; modeling; standardization}, + nlm-id = {101477957}, + owner = {NLM}, + pmc = {PMC4005938}, + pmid = {24795618}, + pubmodel = {Electronic-eCollection}, + pubstatus = {epublish}, + revised = {2018-11-13}, + timestamp = {2019-02-20}, + year = {2014}, +} + diff --git a/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 00000000..ef36addc --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1 @@ +sphinxcontrib-bibtex diff --git a/doc/tools.txt b/doc/tools.txt deleted file mode 100644 index 056aef26..00000000 --- a/doc/tools.txt +++ /dev/null @@ -1,92 +0,0 @@ -Useful tools -============ - -Below is a list of tools which are built in or use Python and which would benefit from a standard library to access, -modify and save detailed neuronal morphologies. Developers from most of these initiatives are involved with the -libNeuroML project. - -Neuronvisio ------------ - -Neuronvisio is a Graphical User Interface for NEURON simulator environment with 3D capabilities. - -http://neuronvisio.org (GitHub: https://github.com/mattions/neuronvisio) - -PyNN ----- - -PyNN is a is a simulator-independent language for building neuronal network models. - -http://neuralensemble.org/trac/PyNN - -Morphforge ----------- - -A Python library for simulating small networks of multicompartmental neurons - -https://github.com/mikehulluk/morphforge - -CATMAID -------- - -We reconstruct neuronal circuits (morphology in 3D, synaptic connectivity) as skeletons, surfaces, volumes in CATMAID. -We want to be able to export the data into an object model (data format), complement it with ion channel distribution of -several types & synaptic mechanisms, and simulate the membrane voltage time series and do virtual current injection etc. -on standard simulators. All of this with a easy-to-use, intuitive Python API in a few lines of code. - -http://www.catmaid.org - -NEURON ------- - -A widely used simulation platform for biophysically detailed neurons and networks which has recently added a Python interface. - -http://www.neuron.yale.edu/neuron - -For more information on Python & NEURON, see Andrew Davison's guide here: http://www.davison.webfactional.com/notes/installation-neuron-python/ - -MOOSE & Moogli --------------- - -MOOSE is the Multiscale Object-Oriented Simulation Environment. It is the base and numerical core for large, detailed simulations including Computational Neuroscience and Systems Biology. - -http://moose.sourceforge.net - -**PyMOOSE** - - -The latest version of MOOSE with a Python interface can be installed as follows: - -:: - - svn co http://moose.svn.sourceforge.net/svnroot/moose/moose/branches/dh_branch moose - cd moose - make pymoose - sudo cp -r python/moose /usr/lib/python2.7/dist-packages - -replacing `/usr/lib/python2.7/dist-packages` with the appropriate location for your Python packages. More details can be found `here `_. - -An example of the HH squid mode can be run with: - -:: - - cd Demos/squid/ - python squid_demo.py - -**Moogli** - -Moogli (a sister project of MOOSE) is a simulator independent OpenGL based visualization tool for neural simulations. -Moogli can visualize morphology of single/multiple neurons or network of neurons, and can also visualize activity in these cells. - -http://moose.ncbs.res.in/moogli/ - - -neuroConstruct --------------- - -neuroConstruct generates native simulator code for NEURON, MOOSE and other simulators. It would be a great benefit to be -able to generate pure NeuroML descriptions of the model components and run (nearly) identical Python code on these -simulators to load the NeuroML and execute the simulations. This scenario is implemented already for a limited number of -model types by generating PyNN based scripts which can run on NEURON, Brian and NEST. - -http://www.neuroConstruct.org diff --git a/doc/utils.rst b/doc/utils.rst new file mode 100644 index 00000000..596faa49 --- /dev/null +++ b/doc/utils.rst @@ -0,0 +1,7 @@ +:mod:`utils` Module +--------------------- + +.. automodule:: neuroml.utils + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/writers.rst b/doc/writers.rst new file mode 100644 index 00000000..723e1457 --- /dev/null +++ b/doc/writers.rst @@ -0,0 +1,8 @@ +:mod:`writers` Module +--------------------- + +.. automodule:: neuroml.writers + :members: + :undoc-members: + :show-inheritance: + diff --git a/neuroml/nml/README.md b/neuroml/nml/README.md index 7fb4b7b8..9a295246 100644 --- a/neuroml/nml/README.md +++ b/neuroml/nml/README.md @@ -16,4 +16,40 @@ You may have to add the current folder to your PYTHONPATH, i.e. export PYTHONPATH=$PYTHONPATH:. -Note from PG Feb 2021: retested & regenerated using Python 2.7 with generateDS.py v2.30.11- currently fails when generated with Python 3... + +Note that generateDS.py will import the generateds_config.py file and run it. +Your output should, therefore, include lines of the form: + + generateds_config.py is being processed + Saving NameTable to csv file: name_table.csv + Saving name changes table to csv file: changed_names.csv + + +If these are not included in the output, generateds_config.py has not run, and the generated nml.py file will be incorrect. + +### Changelog + +#### March 26, 2020 + +Author: @sanjayankur31 + +Resort to using Python 2.7 and generateDS.py 2.30.11 for the time being. + +- all tests and examples pass + +#### March 26, 2020 + +Author: @sanjayankur31 + +Generation attempt using Python 3.9 for NeuroMLv2.1.xsd using generateDS.py 2.38.3: + +- generation requires updating of the generateds_config.py file +- generated nml.py seems to contain issues: https://sourceforge.net/p/generateds/tickets/13/ +- after tweaking nml.py, json serialization example still fails. + + +#### February 2020 + +Author: @pgleeson + +Retested & regenerated using Python 2.7 with generateDS.py v2.30.11- currently fails when generated with Python 3. diff --git a/neuroml/nml/helper_methods.py b/neuroml/nml/helper_methods.py index c39a0071..7c491caa 100644 --- a/neuroml/nml/helper_methods.py +++ b/neuroml/nml/helper_methods.py @@ -802,6 +802,13 @@ def __str__(self): # Get segment object by its id def get_segment(self, segment_id): + """Get segment object by its id + + :param segment_id: ID of segment + :return: segment + + :raises Exception: if the segment is not found in the cell + """ for segment in self.morphology.segments: if segment.id == segment_id: @@ -813,6 +820,16 @@ def get_segment(self, segment_id): # so the proximal point is on the parent (at a point set by fraction_along) def get_actual_proximal(self, segment_id): + """Get the proximal point of a segment. + + Get the proximal point of a segment, even the proximal field is None + and so the proximal point is on the parent (at a point set by + fraction_along). + + :param segment_id: ID of segment + :return: proximal point + """ + segment = self.get_segment(segment_id) if segment.proximal: return segment.proximal @@ -832,6 +849,11 @@ def get_actual_proximal(self, segment_id): return p def get_segment_length(self, segment_id): + """Get the length of the segment. + + :param segment_id: ID of segment + :return: length of segment + """ segment = self.get_segment(segment_id) if segment.proximal: @@ -844,6 +866,11 @@ def get_segment_length(self, segment_id): return length def get_segment_surface_area(self, segment_id): + """Get the surface area of the segment. + + :param segment_id: ID of the segment + :return: surface area of segment + """ segment = self.get_segment(segment_id) if segment.proximal: @@ -856,7 +883,11 @@ def get_segment_surface_area(self, segment_id): return temp_seg.surface_area def get_segment_volume(self, segment_id): + """Get volume of segment + :param segment_id: ID of the segment + :return: volume of the segment + """ segment = self.get_segment(segment_id) if segment.proximal: return segment.volume @@ -868,6 +899,10 @@ def get_segment_volume(self, segment_id): return temp_seg.volume def get_segment_ids_vs_segments(self): + """Get a dictionary of segment IDs and the segments in the cell. + + :return: dictionary with segment ID as key, and segment as value + """ segments = {} for segment in self.morphology.segments: @@ -878,6 +913,18 @@ def get_segment_ids_vs_segments(self): def get_all_segments_in_group(self, segment_group, assume_all_means_all=True): + """Get all the segments in a segment group of the cell. + + :param segment_group: segment group to get all segments of + :param assume_all_means_all: return all segments if the segment group + wasn't explicitly defined + + :todo: check docstring + + :return: list of segments + + :raises Exception: if no segment group is found in the cell. + """ if isinstance(segment_group, str): for sg in self.morphology.segment_groups: @@ -912,6 +959,20 @@ def get_ordered_segments_in_groups(self, include_cumulative_lengths=False, include_path_lengths=False, path_length_metric="Path Length from root"): # Only option supported + """ + Get ordered list of segments in specified groups + + :param group_list: list of groups to get segments from + :param check_parentage: verify parentage + :param include_commulative_lengths: also include cummulative lengths + :param include_path_lengths: also include path lengths + :param path_length_metric: + + :return: dictionary of segments with additional information depending + on what parameters were used: + + :raises: Exception if check_parentage is True and parentage cannot be verified + """ unord_segs = {} other_segs = {} @@ -1022,6 +1083,7 @@ def get_ordered_segments_in_groups(self, def summary(self): + """Print cell summary.""" print("*******************************************************") print("* Cell: "+str(self.id)) print("* Notes: "+str(self.notes)) @@ -1436,12 +1498,14 @@ def exportHdf5(self, h5file, h5Group): source='''\ def _get_cell_id(self,ref): + """Get cell ID""" if '[' in ref: return int(ref.split('[')[1].split(']')[0]) else: return int(ref.split('/')[2]) def _get_population(self,ref): + """Get population""" if '[' in ref: return ref.split('[')[0] else: @@ -1464,12 +1528,14 @@ def __str__(self): source='''\ def get_target_cell_id(self,): + """Get target cell ID""" if '[' in self.target: return int(self.target.split('[')[1].split(']')[0]) else: return int(self.target.split('/')[2]) def get_target_population(self,): + """Get target population.""" if '[' in self.target: return self.target.split('[')[0] else: diff --git a/neuroml/nml/nml.py b/neuroml/nml/nml.py index b8281f42..9456bfb3 100644 --- a/neuroml/nml/nml.py +++ b/neuroml/nml/nml.py @@ -2,12 +2,11 @@ # -*- coding: utf-8 -*- # -# Generated Mon Feb 15 14:47:04 2021 by generateDS.py version 2.30.11. -# Python 2.7.15 |Anaconda, Inc.| (default, Oct 23 2018, 13:35:16) [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] +# Generated Fri Mar 26 16:21:07 2021 by generateDS.py version 2.30.11. +# Python 2.7.18 (default, Feb 3 2021, 00:00:00) [GCC 11.0.0 20210130 (Red Hat 11.0.0-0)] # # Command line options: # ('-o', 'nml.py') -# ('-f', '') # ('--use-getter-setter', 'none') # ('--silence', '') # ('--user-methods', 'helper_methods') @@ -16,7 +15,7 @@ # NeuroML_v2.1.xsd # # Command line: -# /Users/padraig/anaconda/envs/py27/bin/generateDS.py -o "nml.py" -f --use-getter-setter="none" --silence --user-methods="helper_methods" NeuroML_v2.1.xsd +# /home/asinha/.local/share/virtualenvs/generateds-2.7/bin/generateDS.py -o "nml.py" --use-getter-setter="none" --silence --user-methods="helper_methods" NeuroML_v2.1.xsd # # Current working directory (os.getcwd()): # nml @@ -35,7 +34,7 @@ Validate_simpletypes_ = True if sys.version_info.major == 2: - BaseStrType_ = basestring # noqa: F821 + BaseStrType_ = basestring else: BaseStrType_ = str @@ -415,7 +414,7 @@ def gds_encode(instring): def convert_unicode(instring): if isinstance(instring, str): result = quote_xml(instring) - elif sys.version_info.major == 2 and isinstance(instring, unicode): # noqa: F821 + elif sys.version_info.major == 2 and isinstance(instring, unicode): result = quote_xml(instring).encode('utf8') else: result = GeneratedsSuper.gds_encode(str(instring)) @@ -5934,12 +5933,14 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): pass def _get_cell_id(self,ref): + """Get cell ID""" if '[' in ref: return int(ref.split('[')[1].split(']')[0]) else: return int(ref.split('/')[2]) def _get_population(self,ref): + """Get population""" if '[' in ref: return ref.split('[')[0] else: @@ -6068,12 +6069,14 @@ def __str__(self): def get_target_cell_id(self,): + """Get target cell ID""" if '[' in self.target: return int(self.target.split('[')[1].split(']')[0]) else: return int(self.target.split('/')[2]) def get_target_population(self,): + """Get target population.""" if '[' in self.target: return self.target.split('[')[0] else: @@ -17820,6 +17823,13 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): # Get segment object by its id def get_segment(self, segment_id): + """Get segment object by its id + + :param segment_id: ID of segment + :return: segment + + :raises Exception: if the segment is not found in the cell + """ for segment in self.morphology.segments: if segment.id == segment_id: @@ -17831,6 +17841,16 @@ def get_segment(self, segment_id): # so the proximal point is on the parent (at a point set by fraction_along) def get_actual_proximal(self, segment_id): + """Get the proximal point of a segment. + + Get the proximal point of a segment, even the proximal field is None + and so the proximal point is on the parent (at a point set by + fraction_along). + + :param segment_id: ID of segment + :return: proximal point + """ + segment = self.get_segment(segment_id) if segment.proximal: return segment.proximal @@ -17850,6 +17870,11 @@ def get_actual_proximal(self, segment_id): return p def get_segment_length(self, segment_id): + """Get the length of the segment. + + :param segment_id: ID of segment + :return: length of segment + """ segment = self.get_segment(segment_id) if segment.proximal: @@ -17862,6 +17887,11 @@ def get_segment_length(self, segment_id): return length def get_segment_surface_area(self, segment_id): + """Get the surface area of the segment. + + :param segment_id: ID of the segment + :return: surface area of segment + """ segment = self.get_segment(segment_id) if segment.proximal: @@ -17874,7 +17904,11 @@ def get_segment_surface_area(self, segment_id): return temp_seg.surface_area def get_segment_volume(self, segment_id): + """Get volume of segment + :param segment_id: ID of the segment + :return: volume of the segment + """ segment = self.get_segment(segment_id) if segment.proximal: return segment.volume @@ -17886,6 +17920,10 @@ def get_segment_volume(self, segment_id): return temp_seg.volume def get_segment_ids_vs_segments(self): + """Get a dictionary of segment IDs and the segments in the cell. + + :return: dictionary with segment ID as key, and segment as value + """ segments = {} for segment in self.morphology.segments: @@ -17896,6 +17934,18 @@ def get_segment_ids_vs_segments(self): def get_all_segments_in_group(self, segment_group, assume_all_means_all=True): + """Get all the segments in a segment group of the cell. + + :param segment_group: segment group to get all segments of + :param assume_all_means_all: return all segments if the segment group + wasn't explicitly defined + + :todo: check docstring + + :return: list of segments + + :raises Exception: if no segment group is found in the cell. + """ if isinstance(segment_group, str): for sg in self.morphology.segment_groups: @@ -17930,6 +17980,20 @@ def get_ordered_segments_in_groups(self, include_cumulative_lengths=False, include_path_lengths=False, path_length_metric="Path Length from root"): # Only option supported + """ + Get ordered list of segments in specified groups + + :param group_list: list of groups to get segments from + :param check_parentage: verify parentage + :param include_commulative_lengths: also include cummulative lengths + :param include_path_lengths: also include path lengths + :param path_length_metric: + + :return: dictionary of segments with additional information depending + on what parameters were used: + + :raises: Exception if check_parentage is True and parentage cannot be verified + """ unord_segs = {} other_segs = {} @@ -18040,6 +18104,7 @@ def get_ordered_segments_in_groups(self, def summary(self): + """Print cell summary.""" print("*******************************************************") print("* Cell: "+str(self.id)) print("* Notes: "+str(self.notes)) diff --git a/neuroml/test/test_xml_parser.py b/neuroml/test/test_xml_parser.py index 1fa8473f..2fa1824d 100644 --- a/neuroml/test/test_xml_parser.py +++ b/neuroml/test/test_xml_parser.py @@ -15,39 +15,39 @@ except ImportError: import unittest + class TestNeuroMLXMLParser(unittest.TestCase): - + def test_parse(self): - base_dir = os.path.dirname(__file__) #base_dir = '.' - + logging.basicConfig(level=logging.INFO, format="%(name)-19s %(levelname)-5s - %(message)s") - - for f in ['simplenet.nml','testh5.nml','pyr_4_sym.cell.nml','MediumNet.net.nml','complete.nml']: - + + for f in ['simplenet.nml','testh5.nml','pyr_4_sym.cell.nml','MediumNet.net.nml','complete.nml']: + file_name = base_dir+'/../examples/test_files/'+f nml_doc0 = loaders.read_neuroml2_file(file_name, include_includes=True, verbose=True) - + summary0 = nml_doc0.summary(show_includes=False,show_non_network=False) print('\n'+summary0) from neuroml.hdf5.DefaultNetworkHandler import DefaultNetworkHandler - nmlHandler = DefaultNetworkHandler() + nmlHandler = DefaultNetworkHandler() - currParser = NeuroMLXMLParser(nmlHandler) + currParser = NeuroMLXMLParser(nmlHandler) currParser.parse(file_name) print('-------------------------------\n\n') - nmlHandler = NetworkBuilder() + nmlHandler = NetworkBuilder() - currParser = NeuroMLXMLParser(nmlHandler) + currParser = NeuroMLXMLParser(nmlHandler) currParser.parse(file_name) @@ -63,32 +63,28 @@ def test_parse(self): import neuroml.writers as writers writers.NeuroMLWriter.write(nml_doc, nml_file) print("Written network file to: "+nml_file) - - + def runTest(self): print("Running tests in TestNeuroMLXMLParser") - - - + + def compare(s1,s2): - if s1==s2: print("Same!") return - + l1 = s1.split('\n') l2 = s2.split('\n') - + for i in range(min(len(l1),len(l2))): if not l1[i]==l2[i]: print("Mismatch at line %i:\n>>> %s\n<<< %s"%(i,l1[i],l2[i])) if len(l1)!=len(l2): print("Different number of lines!") - + assert(s1==s2) - + if __name__ == '__main__': - tnxp = TestNeuroMLXMLParser() - tnxp.test_parse() \ No newline at end of file + tnxp.test_parse() diff --git a/setup.cfg b/setup.cfg index 72248c82..34ad2ac1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,3 +3,4 @@ # spacing around operators, comment blocks, in argument lists # lines too long ignore = E501,E502,F403,F405,E231,E228,E225,E226,E265,E261 +exclude = neuroml/nml/nml.py